fixed uneccesary statu updates to prevent flashing rerenders on the wordlist etc
This commit is contained in:
parent
62cf2ef4d4
commit
e69fd94d31
|
@ -150,8 +150,14 @@ function setupPassport(passport: PassportStatic) {
|
|||
cb(null, false);
|
||||
return;
|
||||
}
|
||||
const newUser = await updateLingdocsUser(userId, { lastActive: getTimestamp() });
|
||||
cb(null, newUser);
|
||||
try {
|
||||
// skip if there's an update conflict
|
||||
const newUser = await updateLingdocsUser(userId, { lastActive: getTimestamp() });
|
||||
cb(null, newUser);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
cb(null, user);
|
||||
}
|
||||
} catch (err) {
|
||||
cb(err, null);
|
||||
}
|
||||
|
|
|
@ -200,9 +200,9 @@
|
|||
}
|
||||
},
|
||||
"@lingdocs/pashto-inflector": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.9.0.tgz",
|
||||
"integrity": "sha512-kiWVshiMGp/eT0vPTheujD9hJrUXAqLKG48a6iqX8RBURlv5hjk9t+CymKvLGYDO0Zrog0kAYcSo/PqkV0UKIw==",
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.9.2.tgz",
|
||||
"integrity": "sha512-9tmPPezEvPFR/tPkBuF/bj79dCAviFTGOmCVDbRCymXmv4gWWhH4lCueYOYhyWZ4vXcihMflVpRSmLtUDXmdjQ==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.6",
|
||||
"pbf": "^3.2.1",
|
||||
|
@ -1697,9 +1697,9 @@
|
|||
}
|
||||
},
|
||||
"protocol-buffers-schema": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz",
|
||||
"integrity": "sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw=="
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.2.tgz",
|
||||
"integrity": "sha512-LPzSaBYp/TcbuSlpGwqT5jR9kvJ3Zp5ic2N5c2ybx6XB/lSfEHq2D7ja8AgoxHoMD91wXFALJoXsvshKPuXyew=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
|
@ -1745,9 +1745,9 @@
|
|||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"rambda": {
|
||||
"version": "6.8.2",
|
||||
"resolved": "https://registry.npmjs.org/rambda/-/rambda-6.8.2.tgz",
|
||||
"integrity": "sha512-fIVr6nuqfHfJTguthGsWF930DkNq/ENraeSpYBj1kYvO/ieacux7rj2NW27JwwFrllFJwXkLpGyFMz99EwCJ3Q=="
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/rambda/-/rambda-6.9.0.tgz",
|
||||
"integrity": "sha512-yosVdGg1hNGkXPzqGiOYNEpXKjEOxzUCg2rB0l+NKdyCaSf4z+i5ojbN0IqDSezMMf71YEglI+ZUTgTffn5afw=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"main": "lib/functions/src/index.js",
|
||||
"dependencies": {
|
||||
"@google-cloud/storage": "^5.8.1",
|
||||
"@lingdocs/pashto-inflector": "^0.9.0",
|
||||
"@lingdocs/pashto-inflector": "^0.9.2",
|
||||
"@types/cors": "^2.8.10",
|
||||
"@types/google-spreadsheet": "^3.0.2",
|
||||
"cors": "^2.8.5",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.2",
|
||||
"@lingdocs/pashto-inflector": "^0.9.0",
|
||||
"@lingdocs/pashto-inflector": "^0.9.2",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"react-bootstrap": "^1.5.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dropzone": "^11.3.2",
|
||||
"react-firebaseui": "^4.1.0",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-image-crop": "^8.6.9",
|
||||
|
@ -87,14 +86,14 @@
|
|||
"@types/lokijs": "^1.5.3",
|
||||
"@types/mousetrap": "^1.6.8",
|
||||
"@types/papaparse": "^5.2.5",
|
||||
"@types/passport-github2": "^1.2.5",
|
||||
"@types/passport-google-oauth": "^1.0.42",
|
||||
"@types/passport-twitter": "^1.0.37",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"@types/react-canvas-draw": "^1.1.0",
|
||||
"@types/react-helmet": "^6.1.0",
|
||||
"@types/react-image-crop": "^8.1.2",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"@types/passport-github2": "^1.2.5",
|
||||
"@types/passport-google-oauth": "^1.0.42",
|
||||
"@types/passport-twitter": "^1.0.37",
|
||||
"fake-indexeddb": "^3.1.2",
|
||||
"history": "4",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
|
|
|
@ -73,6 +73,7 @@ import "./App.css";
|
|||
import classNames from "classnames";
|
||||
import { getTextOptions } from "./lib/get-text-options";
|
||||
import { getTextFromShareTarget } from "./lib/share-target";
|
||||
import { objIsEqual } from "./lib/misc-helpers";
|
||||
|
||||
// to allow Moustrap key combos even when input fields are in focus
|
||||
Mousetrap.prototype.stopCallback = function () {
|
||||
|
@ -290,8 +291,10 @@ class App extends Component<RouteComponentProps, State> {
|
|||
...userOnServer,
|
||||
userTextOptionsRecord,
|
||||
};
|
||||
this.setState({ user });
|
||||
saveUser(user);
|
||||
if (!objIsEqual(prevUser, user)) {
|
||||
this.setState({ user });
|
||||
saveUser(user);
|
||||
}
|
||||
const textOptionsRecord: TextOptionsRecord = {
|
||||
lastModified: userTextOptionsRecord.lastModified,
|
||||
textOptions: {
|
||||
|
@ -345,7 +348,7 @@ class App extends Component<RouteComponentProps, State> {
|
|||
this.setState({ options });
|
||||
}
|
||||
} else {
|
||||
this.setState({ options });
|
||||
!objIsEqual(this.state.options, options) && this.setState({ options });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,7 +517,8 @@ class App extends Component<RouteComponentProps, State> {
|
|||
</Route>
|
||||
{wordlistEnabled(this.state.user) && <Route path="/wordlist">
|
||||
<Wordlist
|
||||
state={this.state}
|
||||
options={this.state.options}
|
||||
wordlist={this.state.wordlist}
|
||||
isolateEntry={this.handleIsolateEntry}
|
||||
optionsDispatch={this.handleOptionsUpdate}
|
||||
/>
|
||||
|
|
|
@ -8,6 +8,9 @@ const baseUrl: Record<Service, string> = {
|
|||
functions: "https://functions.lingdocs.com/",
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
const sampleAdminUser: AT.LingdocsUser = {"_id":"5e8dd381-950f-4641-922d-c63c6bf0f8e9","_rev":"1713-1a299e0d66da62fe4c8d059f0f068cb7","userId":"5e8dd381-950f-4641-922d-c63c6bf0f8e9","email":"clay@mailbox.org","admin":true,"emailVerified":true,"name":"Adam D","password":"$2a$10$JR4AHXXGbFP6sKQrqGO9UuMa3tdzNhbdqBvkjn2MVBuIOHkA/Xkf.","level":"editor","tests":[],"lastLogin":1629893763810,"lastActive":1630414108552,"userTextOptionsRecord":{"lastModified":1629983812750,"userTextOptions":{"spelling":"Afghan","diacritics":false,"dialect":"standard","phonetics":"lingdocs"}},"github":{"id":"71590811","nodeId":"MDQ6VXNlcjcxNTkwODEx","displayName":"LingDocs","username":"lingdocs","profileUrl":"https://github.com/lingdocs","photos":[{"value":"https://avatars.githubusercontent.com/u/71590811?v=4"}],"provider":"github","accessToken":"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"},"twitter":{"id":"1307635660451385344","username":"lingdocs","displayName":"LingDocs","photos":[{"value":"https://pbs.twimg.com/profile_images/1315656283928899584/EJIqjI-I_normal.jpg"}],"provider":"twitter","_accessLevel":"read","token":"1307635660451385344-MhpGAaJ6hFmfJtV97N6gy11FgbamVX","tokenSecret":"QjouJ33sWb2MpCkcUqqRxbfC9bqDyRaIODO9cejDvdusN"},"wordlistDbName":"userdb-35653864643338312d393530662d343634312d393232642d633633633662663066386539","couchDbPassword":"oevewi8iptdqyxax3v1x7t2ngi4uloir53g2y4659ada","google":{"id":"111202697753203366308","displayName":"Adam Dueck","name":{"familyName":"Dueck","givenName":"Adam"},"emails":[{"value":"lingdocsdev@gmail.com","verified":true}],"photos":[{"value":"https://lh3.googleusercontent.com/a/AATXAJx3cxPPpUoosqVzyGR-LcJ48EjpVcOBInkW21E=s96-c"}],"provider":"google","accessToken":"ya29.a0ARrdaM8BOOmaKxAPe_tKuVq0VgBncURPeEUUqV85RKksibmdx-DSY0IPOGXLs7UB8vh0yIpULsCQHiBKKg_l1DtuEmfwkN7F1h5YDyn2Zwd_ytVTE4W93YvdVGHVnX8rTdlEVcXLO2apwhJrBi3PuzTzxa6BTw"}};
|
||||
|
||||
// FUNCTIONS CALLS - MUST BE RE-ROUTED THROUGH FIREBASE HOSTING IN ../../../firebase.json
|
||||
export async function publishDictionary(): Promise<FT.PublishDictionaryResponse | FT.FunctionError> {
|
||||
return await myFetch("functions", "publishDictionary") as FT.PublishDictionaryResponse | FT.FunctionError;
|
||||
|
@ -41,6 +44,9 @@ export async function signOut() {
|
|||
}
|
||||
|
||||
export async function getUser(): Promise<undefined | AT.LingdocsUser | "offline"> {
|
||||
if (process.env.REACT_APP_ENV === "dev") {
|
||||
return sampleAdminUser;
|
||||
}
|
||||
try {
|
||||
const response = await myFetch("account", "user");
|
||||
if ("user" in response) {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export function objIsEqual(obj1: any, obj2: any): boolean {
|
||||
if (!obj1 || !obj2) return false;
|
||||
return JSON.stringify(obj1) === JSON.stringify(obj2);
|
||||
}
|
|
@ -44,7 +44,6 @@ import AudioPlayButton from "../components/AudioPlayButton";
|
|||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime.js";
|
||||
import hitBottom from "../lib/hitBottom";
|
||||
import { getTextOptions } from "../lib/get-text-options";
|
||||
|
||||
const cleanupIcon = "broom";
|
||||
|
||||
|
@ -72,8 +71,9 @@ function amountOfWords(number: number): string {
|
|||
return `${number} word${number !== 1 ? "s" : ""}`;
|
||||
}
|
||||
|
||||
function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
||||
state: State,
|
||||
function Wordlist({ options, wordlist, isolateEntry, optionsDispatch }: {
|
||||
options: Options,
|
||||
wordlist: WordlistWord[],
|
||||
isolateEntry: (ts: number) => void,
|
||||
optionsDispatch: (action: OptionsAction) => void,
|
||||
}) {
|
||||
|
@ -89,17 +89,17 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
const [showingCleanup, setShowingCleanup] = useState<boolean>(false);
|
||||
const [monthsBackToKeep, setMonthsBackToKeep] = useState<number>(6);
|
||||
const [wordsToDelete, setWordsToDelete] = useState<string[]>([]);
|
||||
const [startedWithWordsToReview] = useState<boolean>(forReview(state.wordlist).length !== 0);
|
||||
const [startedWithWordsToReview] = useState<boolean>(forReview(wordlist).length !== 0);
|
||||
useEffect(() => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
const toReview = forReview(state.wordlist);
|
||||
const textOptions = getTextOptions(state);
|
||||
const toReview = forReview(wordlist);
|
||||
const textOptions = options.textOptionsRecord.textOptions;
|
||||
function handleScroll() {
|
||||
// TODO: DON'T HAVE ENDLESS PAGE INCREASING
|
||||
if (hitBottom() && state.options.wordlistMode === "browse") {
|
||||
if (hitBottom() && options.wordlistMode === "browse") {
|
||||
setPage(page => page + 1);
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
}
|
||||
function handleSearchValueChange(value: string) {
|
||||
setWordlistSearchValue(value);
|
||||
const results = value ? searchWordlist(value, state.wordlist, textOptions) : [];
|
||||
const results = value ? searchWordlist(value, wordlist, textOptions) : [];
|
||||
setFilteredWords(results);
|
||||
}
|
||||
async function handleGetWordlistCSV() {
|
||||
|
@ -137,7 +137,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
}
|
||||
function handleShowCleanup() {
|
||||
setWordsToDelete(
|
||||
calculateWordsToDelete(state.wordlist, monthsBackToKeep)
|
||||
calculateWordsToDelete(wordlist, monthsBackToKeep)
|
||||
);
|
||||
setShowingCleanup(true);
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
setWordsToDelete([]);
|
||||
}
|
||||
function handleCleanup() {
|
||||
const toDelete = calculateWordsToDelete(state.wordlist, monthsBackToKeep);
|
||||
const toDelete = calculateWordsToDelete(wordlist, monthsBackToKeep);
|
||||
deleteWordFromWordlist(toDelete);
|
||||
setShowingCleanup(false);
|
||||
}
|
||||
|
@ -219,13 +219,13 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
<div className="card mb-3 clickable" onClick={() => handleWordClickReview(word._id)}>
|
||||
<div className="card-body">
|
||||
<h6 className="card-title text-center">
|
||||
{state.options.wordlistReviewLanguage === "Pashto"
|
||||
{options.wordlistReviewLanguage === "Pashto"
|
||||
? <InlinePs opts={textOptions}>{{ p: word.entry.p, f: word.entry.f }}</InlinePs>
|
||||
: word.entry.e
|
||||
}
|
||||
</h6>
|
||||
{beingQuizzed && <div className="card-text text-center">
|
||||
{state.options.wordlistReviewLanguage === "Pashto"
|
||||
{options.wordlistReviewLanguage === "Pashto"
|
||||
? <div>{word.entry.e}</div>
|
||||
: <InlinePs opts={textOptions}>
|
||||
{{ p: word.entry.p, f: word.entry.f }}
|
||||
|
@ -249,7 +249,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
</Helmet>
|
||||
<div className="d-flex flex-row justify-content-between mb-2">
|
||||
<h4 className="mb-3">Wordlist</h4>
|
||||
{state.wordlist.length > 0 &&
|
||||
{wordlist.length > 0 &&
|
||||
<div className="d-flex flex-row justify-content-between mb-2">
|
||||
<div>
|
||||
<button className="btn btn-sm btn-outline-secondary mr-3" onClick={handleShowCleanup}>
|
||||
|
@ -264,7 +264,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
</div>
|
||||
}
|
||||
</div>
|
||||
{!state.wordlist.length ?
|
||||
{!wordlist.length ?
|
||||
<EmptyWordlistNotice />
|
||||
:
|
||||
<>
|
||||
|
@ -280,16 +280,16 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
value: "review",
|
||||
},
|
||||
]}
|
||||
value={state.options.wordlistMode || "browse"}
|
||||
value={options.wordlistMode || "browse"}
|
||||
handleChange={(p) => {
|
||||
optionsDispatch({ type: "changeWordlistMode", payload: p as WordlistMode });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{state.options.wordlistMode === "browse"
|
||||
{options.wordlistMode === "browse"
|
||||
? <div className="mt-4">
|
||||
<WordlistSearchBar value={wordlistSearchValue} handleChange={handleSearchValueChange} />
|
||||
{paginate(wordlistSearchValue ? filteredWords : state.wordlist, page).map((word) => (
|
||||
{paginate(wordlistSearchValue ? filteredWords : wordlist, page).map((word) => (
|
||||
<WordlistBrowsingWord word={word} key={word._id} />
|
||||
))}
|
||||
</div>
|
||||
|
@ -298,7 +298,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
<div className="mb-4 text-center" style={{ width: "100%" }}>
|
||||
<ButtonSelect
|
||||
options={reviewLanguageOptions}
|
||||
value={state.options.wordlistReviewLanguage || "Pashto"}
|
||||
value={options.wordlistReviewLanguage || "Pashto"}
|
||||
handleChange={(p) => {
|
||||
optionsDispatch({ type: "changeWordlistReviewLanguage", payload: p as Language });
|
||||
}}
|
||||
|
@ -310,7 +310,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
? (startedWithWordsToReview
|
||||
? <p className="lead my-3">All done review 🎉</p>
|
||||
: (() => {
|
||||
const nextUp = nextUpForReview(state.wordlist);
|
||||
const nextUp = nextUpForReview(wordlist);
|
||||
const { e, ...ps } = nextUp.entry;
|
||||
return <div>
|
||||
<div className="lead my-3">None to review</div>
|
||||
|
@ -370,7 +370,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
<Modal.Title><i className={`fas fa-${cleanupIcon} mr-1`} /> Wordlist Cleanup</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<p>You have {amountOfWords(state.wordlist.length)} in your wordlist.</p>
|
||||
<p>You have {amountOfWords(wordlist.length)} in your wordlist.</p>
|
||||
<p>Delete words older than:</p>
|
||||
<ButtonSelect
|
||||
options={[
|
||||
|
@ -391,7 +391,7 @@ function Wordlist({ state, isolateEntry, optionsDispatch }: {
|
|||
handleChange={(p: string) => {
|
||||
const months = parseInt(p);
|
||||
setWordsToDelete(
|
||||
calculateWordsToDelete(state.wordlist, months),
|
||||
calculateWordsToDelete(wordlist, months),
|
||||
);
|
||||
setMonthsBackToKeep(months);
|
||||
}}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"downlevelIteration": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
|
|
@ -1483,10 +1483,10 @@
|
|||
"@types/yargs" "^16.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@lingdocs/pashto-inflector@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.9.0.tgz#d4aa0154f65b27b27cafdbbd1881d00aa1cc43cb"
|
||||
integrity sha512-kiWVshiMGp/eT0vPTheujD9hJrUXAqLKG48a6iqX8RBURlv5hjk9t+CymKvLGYDO0Zrog0kAYcSo/PqkV0UKIw==
|
||||
"@lingdocs/pashto-inflector@^0.9.2":
|
||||
version "0.9.2"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.9.2.tgz#7ef3b3344c3eb3e3d1db77142ef83f0ac7e8e230"
|
||||
integrity sha512-9tmPPezEvPFR/tPkBuF/bj79dCAviFTGOmCVDbRCymXmv4gWWhH4lCueYOYhyWZ4vXcihMflVpRSmLtUDXmdjQ==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
pbf "^3.2.1"
|
||||
|
@ -4781,11 +4781,6 @@ detect-port-alt@1.1.6:
|
|||
address "^1.0.1"
|
||||
debug "^2.6.0"
|
||||
|
||||
dialog-polyfill@^0.4.7:
|
||||
version "0.4.10"
|
||||
resolved "https://registry.yarnpkg.com/dialog-polyfill/-/dialog-polyfill-0.4.10.tgz#c4ea68a0deed4abb59a6a2a025c548b278cd532e"
|
||||
integrity sha512-j5yGMkP8T00UFgyO+78OxiN5vC5dzRQF3BEio+LhNvDbyfxWBsi3sfPArDm54VloaJwy2hm3erEiDWqHRC8rzw==
|
||||
|
||||
diff-sequences@^26.6.2:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
|
||||
|
@ -5837,14 +5832,6 @@ find-up@^3.0.0:
|
|||
dependencies:
|
||||
locate-path "^3.0.0"
|
||||
|
||||
firebaseui@^4.7.1:
|
||||
version "4.8.1"
|
||||
resolved "https://registry.yarnpkg.com/firebaseui/-/firebaseui-4.8.1.tgz#29ccbc9dfd579c4453725f88e9cf81c8ea62c580"
|
||||
integrity sha512-Qh8kfqGjMIiVJ2X8MUFsmlf43QFcVc8ungD+kw5T8ACuhQ68IAyUHExlItAfumrcLlqEgyo1MjH0O9fZZAMOKw==
|
||||
dependencies:
|
||||
dialog-polyfill "^0.4.7"
|
||||
material-design-lite "^1.2.0"
|
||||
|
||||
flat-cache@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
|
||||
|
@ -8201,11 +8188,6 @@ map-visit@^1.0.0:
|
|||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
material-design-lite@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/material-design-lite/-/material-design-lite-1.3.0.tgz#d004ce3fee99a1eeb74a78b8a325134a5f1171d3"
|
||||
integrity sha1-0ATOP+6Zoe63Sni4oyUTSl8RcdM=
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||
|
@ -10527,13 +10509,6 @@ react-fast-compare@^3.1.1:
|
|||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
||||
|
||||
react-firebaseui@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-firebaseui/-/react-firebaseui-4.2.0.tgz#13846381daefe31b90af98854f3e79e82d4f81ba"
|
||||
integrity sha512-KRWfQn7iJMMAcB1zmMrpo5PJ7CBrLW6NXvdEJ/N+SFZUs7ANvC3g8LzgYwsBHUr1OR1MQtGosV7dyQSmYtKyOA==
|
||||
dependencies:
|
||||
firebaseui "^4.7.1"
|
||||
|
||||
react-ga@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.0.tgz#c91f407198adcb3b49e2bc5c12b3fe460039b3ca"
|
||||
|
|
Loading…
Reference in New Issue