update base
This commit is contained in:
parent
b591379a59
commit
2d87556184
12
.babelrc
12
.babelrc
|
@ -1,11 +1,3 @@
|
|||
{
|
||||
"presets": ["babel-preset-react-app"],
|
||||
"plugins": [
|
||||
[
|
||||
"@babel/plugin-transform-react-jsx",
|
||||
{
|
||||
"pragmaFrag": "React.Fragment"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
"presets": ["babel-preset-react-app"]
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"rules": {
|
||||
"jsx-a11y/accessible-emoji": "off"
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '*' ]
|
||||
pull_request:
|
||||
branches: [ '*' ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LINGDOCS_NPM_TOKEN: ${{ secrets.LINGDOCS_NPM_TOKEN }}
|
||||
LINGDOCS_DICTIONARY_URL: ${{ secrets.LINGDOCS_DICTIONARY_URL }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
- run: yarn install
|
||||
- run: yarn build
|
|
@ -1,9 +1,5 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dictionary entries fetched during build
|
||||
/src/words/**/verbs.js
|
||||
/src/words/**/nouns-adjs.js
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
|
|
2
.npmrc
2
.npmrc
|
@ -1,2 +0,0 @@
|
|||
@lingdocs:registry=https://npm.lingdocs.com
|
||||
//npm.lingdocs.com/:_authToken=${LINGDOCS_NPM_TOKEN}
|
24
README.md
24
README.md
|
@ -1,9 +1,21 @@
|
|||
# LingDocs Pashto Grammar
|
||||
# Create React App w/ MDX Starter
|
||||
|
||||
[![Netlify Status](https://api.netlify.com/api/v1/badges/150beb8b-aae1-4cef-a05c-2add5d8904f7/deploy-status)](https://app.netlify.com/sites/pashto-grammar/deploys)
|
||||
![build](https://github.com/lingdocs/grammar.lingdocs.com/actions/workflows/main.yml/badge.svg)
|
||||
A boilerplate for Create React App projects w/ MDX import functionality
|
||||
|
||||
The source code of this app is licensed under an MIT license.
|
||||
Bootstrapped with:
|
||||
|
||||
The contents of the book, however, (found in `/src/content`) are licensed under a [Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0)](
|
||||
https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
- [Create React App](https://reactjs.org/docs/create-a-new-react-app.html)
|
||||
- [@lingdocs/mdx-loader](https://github.com/lingdocs/mdx-loader)
|
||||
|
||||
### Development
|
||||
|
||||
```
|
||||
yarn install
|
||||
yarn start
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
[0122/001738.459:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
|
62
package.json
62
package.json
|
@ -1,51 +1,45 @@
|
|||
{
|
||||
"name": "lingdocs-pashto-grammar",
|
||||
"name": "lingdocs-grammar",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.2",
|
||||
"@lingdocs/lingdocs-main": "^0.1.8",
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.2.0",
|
||||
"@lingdocs/pashto-inflector": "^1.1.9",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^14.14.35",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/react-router-dom": "^5.1.9",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"@types/cron": "^1.7.3",
|
||||
"@types/react-router-dom": "^5.3.1",
|
||||
"bootstrap": "4.5.3",
|
||||
"classnames": "^2.2.6",
|
||||
"cron": "^1.8.2",
|
||||
"markdown-to-jsx": "^7.1.3",
|
||||
"react": "^17.0.1",
|
||||
"react-bootstrap": "^1.5.2",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^1.6.4",
|
||||
"react-countdown-circle-timer": "^2.5.4",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-media": "^1.10.0",
|
||||
"react-rewards": "^1.1.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-router-hash-link": "^2.3.1",
|
||||
"react-scripts": "3.4.3",
|
||||
"react-router-dom": "^5.3.0",
|
||||
"react-router-hash-link": "^2.4.3",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-scrollspy": "^3.4.3",
|
||||
"react-smooth-collapse": "^2.1.0",
|
||||
"react-swipeable": "^6.1.0",
|
||||
"typescript": "^4.2.3"
|
||||
"react-swipeable": "^6.2.0",
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"start-w-user": "REACT_APP_ENV=dev react-scripts start",
|
||||
"build": "node scripts/get-words.js && react-scripts build",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"get-words": "node scripts/get-words.js"
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app",
|
||||
"rules": {
|
||||
"jsx-a11y/accessible-emoji": "off"
|
||||
}
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
@ -60,9 +54,13 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-react-jsx": "^7.14.5",
|
||||
"@types/cron": "^1.7.3",
|
||||
"mdx-loader": "^3.0.2",
|
||||
"node-fetch": "^2.6.1"
|
||||
"@lingdocs/mdx-loader": "^0.0.8",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^16.10.3",
|
||||
"@types/react": "^17.0.27",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"babel-loader": "8.1.0",
|
||||
"node-fetch": "^3.0.0",
|
||||
"typescript": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
/**
|
||||
* Copyright (c) 2021 lingdocs.com
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders', () => {
|
||||
const { getByText } = render(<App />);
|
||||
const linkElement = getByText(/pashto grammar/i);
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
// eslint-disable-next-line
|
||||
import { BrowserRouter as Router, Route, withRouter, Switch, RouteComponentProps } from "react-router-dom";
|
||||
import "./App.css";
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import leftChevron from "./chevron_left-24px.svg";
|
||||
import rightChevron from "./chevron_right-24px.svg";
|
||||
|
@ -16,7 +16,7 @@ const chevStyle = {
|
|||
width: "3.5rem",
|
||||
};
|
||||
|
||||
export default function(props) {
|
||||
export default function Carousel(props) {
|
||||
// console.log("pppp");
|
||||
// console.log(props.items);
|
||||
const [current, setCurrent] = useState(0);
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { HashLink } from 'react-router-hash-link';
|
||||
import { Link } from "react-router-dom";
|
||||
// import scrollWithOffset from "../../lib/scroll-with-offset.js";
|
||||
|
||||
export default function(props) {
|
||||
export default function L(props) {
|
||||
const { to } = props || "";
|
||||
if (to.includes("#")) {
|
||||
// If it's a hash link return the special hash link
|
||||
|
|
|
@ -8,75 +8,75 @@
|
|||
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
// @ts-ignore
|
||||
import * as intro from "!babel-loader!mdx-loader!./intro.mdx";
|
||||
import * as intro from "!babel-loader!@lingdocs/mdx-loader!./intro.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as presentEquative from "!babel-loader!mdx-loader!./equatives/present-equative.mdx"
|
||||
import * as presentEquative from "!babel-loader!@lingdocs/mdx-loader!./equatives/present-equative.mdx"
|
||||
// @ts-ignore
|
||||
import * as subjunctiveHabitualEquative from "!babel-loader!mdx-loader!./equatives/subjunctive-habitual-equative.mdx";
|
||||
import * as subjunctiveHabitualEquative from "!babel-loader!@lingdocs/mdx-loader!./equatives/subjunctive-habitual-equative.mdx";
|
||||
// @ts-ignore
|
||||
import * as otherEquatives from "!babel-loader!mdx-loader!./equatives/other-equatives.mdx";
|
||||
import * as otherEquatives from "!babel-loader!@lingdocs/mdx-loader!./equatives/other-equatives.mdx";
|
||||
// @ts-ignore
|
||||
import * as equativeExplorer from "!babel-loader!mdx-loader!./equatives/equative-explorer.mdx";
|
||||
import * as equativeExplorer from "!babel-loader!@lingdocs/mdx-loader!./equatives/equative-explorer.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as nounsGender from "!babel-loader!mdx-loader!./nouns/nouns-gender.mdx";
|
||||
import * as nounsGender from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-gender.mdx";
|
||||
// @ts-ignore
|
||||
import * as nounsUnisex from "!babel-loader!mdx-loader!./nouns/nouns-unisex.mdx";
|
||||
import * as nounsUnisex from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-unisex.mdx";
|
||||
// @ts-ignore
|
||||
import * as nounsPlural from "!babel-loader!mdx-loader!./nouns/nouns-plural.mdx";
|
||||
import * as nounsPlural from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-plural.mdx";
|
||||
// @ts-ignore
|
||||
import * as arabicPlurals from "!babel-loader!mdx-loader!./nouns/arabic-plurals.mdx";
|
||||
import * as arabicPlurals from "!babel-loader!@lingdocs/mdx-loader!./nouns/arabic-plurals.mdx";
|
||||
// @ts-ignore
|
||||
import * as bundledPlurals from "!babel-loader!mdx-loader!./nouns/bundled-plurals.mdx";
|
||||
import * as bundledPlurals from "!babel-loader!@lingdocs/mdx-loader!./nouns/bundled-plurals.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as verbAspect from "!babel-loader!mdx-loader!./verbs/verb-aspect.mdx";
|
||||
import * as verbAspect from "!babel-loader!@lingdocs/mdx-loader!./verbs/verb-aspect.mdx";
|
||||
// @ts-ignore
|
||||
import * as verbsIntro from "!babel-loader!mdx-loader!./verbs/verbs-intro.mdx";
|
||||
import * as verbsIntro from "!babel-loader!@lingdocs/mdx-loader!./verbs/verbs-intro.mdx";
|
||||
// @ts-ignore
|
||||
import * as presentVerbs from "!babel-loader!mdx-loader!./verbs/present-verbs.mdx";
|
||||
import * as presentVerbs from "!babel-loader!@lingdocs/mdx-loader!./verbs/present-verbs.mdx";
|
||||
// @ts-ignore
|
||||
import * as subjunctiveVerbs from "!babel-loader!mdx-loader!./verbs/subjunctive-verbs.mdx";
|
||||
import * as subjunctiveVerbs from "!babel-loader!@lingdocs/mdx-loader!./verbs/subjunctive-verbs.mdx";
|
||||
// @ts-ignore
|
||||
import * as futureVerbs from "!babel-loader!mdx-loader!./verbs/future-verbs.mdx";
|
||||
import * as futureVerbs from "!babel-loader!@lingdocs/mdx-loader!./verbs/future-verbs.mdx";
|
||||
// @ts-ignore
|
||||
import * as imperativeVerbs from "!babel-loader!mdx-loader!./verbs/imperative-verbs.mdx";
|
||||
import * as imperativeVerbs from "!babel-loader!@lingdocs/mdx-loader!./verbs/imperative-verbs.mdx";
|
||||
// @ts-ignore
|
||||
import * as verbEndings from "!babel-loader!mdx-loader!./verbs/verb-endings.mdx";
|
||||
import * as verbEndings from "!babel-loader!@lingdocs/mdx-loader!./verbs/verb-endings.mdx";
|
||||
// @ts-ignore
|
||||
import * as rootsAndStems from "!babel-loader!mdx-loader!./verbs/roots-and-stems.mdx";
|
||||
import * as rootsAndStems from "!babel-loader!@lingdocs/mdx-loader!./verbs/roots-and-stems.mdx";
|
||||
// @ts-ignore
|
||||
import * as sentenceStructure from "!babel-loader!mdx-loader!./verbs/sentence-structure.mdx";
|
||||
import * as sentenceStructure from "!babel-loader!@lingdocs/mdx-loader!./verbs/sentence-structure.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as pronounsBasic from "!babel-loader!mdx-loader!./pronouns/pronouns-basic.mdx";
|
||||
import * as pronounsBasic from "!babel-loader!@lingdocs/mdx-loader!./pronouns/pronouns-basic.mdx";
|
||||
// @ts-ignore
|
||||
import * as pronounsMini from "!babel-loader!mdx-loader!./pronouns/pronouns-mini.mdx";
|
||||
import * as pronounsMini from "!babel-loader!@lingdocs/mdx-loader!./pronouns/pronouns-mini.mdx";
|
||||
// @ts-ignore
|
||||
import * as directionalPronouns from "!babel-loader!mdx-loader!./pronouns/pronouns-directional.mdx";
|
||||
import * as directionalPronouns from "!babel-loader!@lingdocs/mdx-loader!./pronouns/pronouns-directional.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as inflectionIntro from "!babel-loader!mdx-loader!./inflection/inflection-intro.mdx";
|
||||
import * as inflectionIntro from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-intro.mdx";
|
||||
// @ts-ignore
|
||||
import * as inflectionPatterns from "!babel-loader!mdx-loader!./inflection/inflection-patterns.mdx";
|
||||
import * as inflectionPatterns from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-patterns.mdx";
|
||||
// @ts-ignore
|
||||
import * as feminineInflection from "!babel-loader!mdx-loader!./inflection/feminine-inflection.mdx";
|
||||
import * as feminineInflection from "!babel-loader!@lingdocs/mdx-loader!./inflection/feminine-inflection.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as sandwiches from "!babel-loader!mdx-loader!./sandwiches/sandwiches.mdx";
|
||||
import * as sandwiches from "!babel-loader!@lingdocs/mdx-loader!./sandwiches/sandwiches.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as phonetics from "!babel-loader!mdx-loader!./writing/phonetics.mdx";
|
||||
import * as phonetics from "!babel-loader!@lingdocs/mdx-loader!./writing/phonetics.mdx";
|
||||
// @ts-ignore
|
||||
import * as diacritics from "!babel-loader!mdx-loader!./writing/diacritics.mdx";
|
||||
import * as diacritics from "!babel-loader!@lingdocs/mdx-loader!./writing/diacritics.mdx";
|
||||
// @ts-ignore
|
||||
import * as theFiveYeys from "!babel-loader!mdx-loader!./writing/the-five-yeys.mdx";
|
||||
import * as theFiveYeys from "!babel-loader!@lingdocs/mdx-loader!./writing/the-five-yeys.mdx";
|
||||
// @ts-ignore
|
||||
import * as typingIssues from "!babel-loader!mdx-loader!./writing/typing-issues.mdx";
|
||||
import * as typingIssues from "!babel-loader!@lingdocs/mdx-loader!./writing/typing-issues.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as games from "!babel-loader!mdx-loader!./games.mdx";
|
||||
import * as games from "!babel-loader!@lingdocs/mdx-loader!./games.mdx";
|
||||
|
||||
const contentTree = [
|
||||
{
|
||||
|
@ -327,29 +327,3 @@ export const content = contentTree.map((item) => {
|
|||
)),
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// // Now that the paths are made, go through and make the next and previous page information for each chapter
|
||||
// // STEP #2
|
||||
// content.sections.forEach((section, i) => {
|
||||
// section.chapters.forEach((chapter, j) => {
|
||||
// // See if there's a next chapter
|
||||
// let nextChapter = j === section.chapters.length - 1 ? null : section.chapters[j + 1];
|
||||
// if (!nextChapter) {
|
||||
// // No? maybe there's something a section ahead (if that exists)
|
||||
// nextChapter = i === content.sections.length - 1 ? null : content.sections[i + 1].chapters[0];
|
||||
// }
|
||||
// if (nextChapter) {
|
||||
// chapter.next = { frontMatter: nextChapter, path: nextChapter.path };
|
||||
// }
|
||||
// // See if there's a previous chapter
|
||||
// let prevChapter = j === 0 ? null : section.chapters[j - 1];
|
||||
// if (!prevChapter) {
|
||||
// // No? maybe there's something a section behind (if that exists)
|
||||
// prevChapter = i === 0 ? null : content.sections[i - 1].chapters[content.sections[i - 1].chapters.length - 1];
|
||||
// }
|
||||
// if (prevChapter) {
|
||||
// chapter.previous = { frontMatter: prevChapter, path: prevChapter.path };
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useRef } from "react";
|
||||
import { useState, useRef } from "react";
|
||||
import { CountdownCircleTimer } from "react-countdown-circle-timer";
|
||||
import Reward, { RewardElement } from 'react-rewards';
|
||||
import Link from "../components/Link";
|
||||
|
@ -16,14 +16,14 @@ import {
|
|||
getTimestamp,
|
||||
} from "@lingdocs/lingdocs-main";
|
||||
import {
|
||||
Types as T,
|
||||
Types,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
const errorVibration = 200;
|
||||
|
||||
function GameCore<T>({ questions, Display, timeLimit, Instructions, studyLink, id }:{
|
||||
id: string,
|
||||
studyLink: string,
|
||||
Instructions: (props: { opts?: T.TextOptions }) => JSX.Element,
|
||||
Instructions: (props: { opts?: Types.TextOptions }) => JSX.Element,
|
||||
questions: () => QuestionGenerator<T>,
|
||||
Display: (props: QuestionDisplayProps<T>) => JSX.Element,
|
||||
timeLimit: number;
|
||||
|
|
|
@ -50,7 +50,7 @@ const exceptions: Record<string, CategorySet> = {
|
|||
|
||||
const amount = 35;
|
||||
|
||||
export default function({level, id, link}: { level: 1 | 2, id: string, link: string }) {
|
||||
export default function GenderGame({level, id, link}: { level: 1 | 2, id: string, link: string }) {
|
||||
function* questions () {
|
||||
const wordPool = {...types};
|
||||
const exceptionsPool = {...exceptions};
|
||||
|
|
|
@ -34,7 +34,7 @@ const amount = 20;
|
|||
|
||||
type Question = { entry: T.DictionaryEntry, gender: T.Gender };
|
||||
|
||||
export default function({ id, link }: { id: string, link: string }) {
|
||||
export default function UnisexNounGame({ id, link }: { id: string, link: string }) {
|
||||
function* questions (): Generator<Current<Question>> {
|
||||
let pool = [...nouns];
|
||||
for (let i = 0; i < amount; i++) {
|
||||
|
|
30
src/index.js
30
src/index.js
|
@ -1,19 +1,12 @@
|
|||
/**
|
||||
* Copyright (c) 2021 lingdocs.com
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import { UserProvider} from "./user-context";
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import "@fortawesome/fontawesome-free/css/all.css";
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
|
@ -28,17 +21,10 @@ ReactDOM.render(
|
|||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.register();
|
||||
// serviceWorker.register({
|
||||
// onUpdate: registration => {
|
||||
// const ready = window.confirm("New version available! Update?");
|
||||
// if (registration && registration.waiting) {
|
||||
// registration.waiting.postMessage({ type: 'SKIP_WAITING' });
|
||||
// }
|
||||
// if (ready) {
|
||||
// window.location.reload();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// Learn more about service workers: https://cra.link/PWA
|
||||
serviceWorkerRegistration.unregister();
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export default {
|
||||
const gc = {
|
||||
m: "#C1D5F4",
|
||||
f: "#FFECEF",
|
||||
}
|
||||
};
|
||||
|
||||
export default gc;
|
|
@ -6,9 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
export default function() {
|
||||
export default function FourOFour() {
|
||||
return <main className="col bg-faded py-3">
|
||||
<h1>404 PAGE NOT FOUND</h1>
|
||||
</main>;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
|
@ -0,0 +1,72 @@
|
|||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
// This service worker can be customized!
|
||||
// See https://developers.google.com/web/tools/workbox/modules
|
||||
// for the list of available Workbox modules, or add any other
|
||||
// code you'd like.
|
||||
// You can also remove this file if you'd prefer not to use a
|
||||
// service worker, and the Workbox build step will be skipped.
|
||||
|
||||
import { clientsClaim } from 'workbox-core';
|
||||
import { ExpirationPlugin } from 'workbox-expiration';
|
||||
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
|
||||
import { registerRoute } from 'workbox-routing';
|
||||
import { StaleWhileRevalidate } from 'workbox-strategies';
|
||||
|
||||
clientsClaim();
|
||||
|
||||
// Precache all of the assets generated by your build process.
|
||||
// Their URLs are injected into the manifest variable below.
|
||||
// This variable must be present somewhere in your service worker file,
|
||||
// even if you decide not to use precaching. See https://cra.link/PWA
|
||||
precacheAndRoute(self.__WB_MANIFEST);
|
||||
|
||||
// Set up App Shell-style routing, so that all navigation requests
|
||||
// are fulfilled with your index.html shell. Learn more at
|
||||
// https://developers.google.com/web/fundamentals/architecture/app-shell
|
||||
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
|
||||
registerRoute(
|
||||
// Return false to exempt requests from being fulfilled by index.html.
|
||||
({ request, url }) => {
|
||||
// If this isn't a navigation, skip.
|
||||
if (request.mode !== 'navigate') {
|
||||
return false;
|
||||
} // If this is a URL that starts with /_, skip.
|
||||
|
||||
if (url.pathname.startsWith('/_')) {
|
||||
return false;
|
||||
} // If this looks like a URL for a resource, because it contains // a file extension, skip.
|
||||
|
||||
if (url.pathname.match(fileExtensionRegexp)) {
|
||||
return false;
|
||||
} // Return true to signal that we want to use the handler.
|
||||
|
||||
return true;
|
||||
},
|
||||
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
|
||||
);
|
||||
|
||||
// An example runtime caching route for requests that aren't handled by the
|
||||
// precache, in this case same-origin .png requests like those from in public/
|
||||
registerRoute(
|
||||
// Add in any other file extensions or routing criteria as needed.
|
||||
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
|
||||
new StaleWhileRevalidate({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
// Ensure that once this runtime cache reaches a maximum size the
|
||||
// least-recently used images are removed.
|
||||
new ExpirationPlugin({ maxEntries: 50 }),
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// This allows the web app to trigger skipWaiting via
|
||||
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
// Any other custom service worker logic can go here.
|
|
@ -8,16 +8,14 @@
|
|||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
// opt-in, read https://cra.link/PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
|
@ -43,7 +41,7 @@ export function register(config) {
|
|||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
'worker. To learn more, visit https://cra.link/PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
|
@ -57,7 +55,7 @@ export function register(config) {
|
|||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
|
@ -71,7 +69,7 @@ function registerValidSW(swUrl, config) {
|
|||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
'tabs for this page are closed. See https://cra.link/PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
|
@ -93,7 +91,7 @@ function registerValidSW(swUrl, config) {
|
|||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
@ -103,7 +101,7 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' },
|
||||
})
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
|
@ -111,7 +109,7 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
|
@ -122,20 +120,18 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
console.log('No internet connection found. App is running in offline mode.');
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then(registration => {
|
||||
.then((registration) => {
|
||||
registration.unregister();
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,4 +2,4 @@
|
|||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import '@testing-library/jest-dom';
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,8 @@
|
|||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react"
|
||||
"jsx": "react-jsx",
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
|
|
Loading…
Reference in New Issue