From c4773dc90427235e913db9bb439ef309b2e431c1 Mon Sep 17 00:00:00 2001
From: Luke Channings <461449+LukeChannings@users.noreply.github.com>
Date: Mon, 23 Oct 2023 22:20:47 +0100
Subject: [PATCH] Landing page improvements and various supporting improvements
---
.github/workflows/run-tests.yaml | 9 +-
.gitignore | 2 +
apple/gql-server/package.json | 5 +-
package.json | 17 +-
packages/api/package.json | 4 +-
packages/appreader/package.json | 5 +-
packages/appreader/webpack.config.ts | 5 +
packages/content-fetch/package.json | 3 +
packages/content-handler/package.json | 4 +
.../src/websites/twitter-handler.ts | 4 +-
packages/cypress/package.json | 5 +-
packages/db/package.json | 1 +
packages/import-handler/package.json | 4 +
packages/inbound-email-handler/package.json | 4 +
packages/pdf-handler/package.json | 4 +
packages/puppeteer-parse/package.json | 3 +
packages/queue-manager/package.json | 4 +
packages/readabilityjs/package.json | 3 +
packages/rss-handler/package.json | 4 +
packages/rule-handler/package.json | 4 +
packages/text-to-speech/package.json | 4 +
packages/thumbnail-handler/package.json | 4 +
packages/web/components/elements/Button.tsx | 19 +-
.../web/components/elements/HeaderNavLink.tsx | 56 +-
.../elements/LabelColorDropdown.tsx | 9 +-
.../web/components/elements/LabelsPicker.tsx | 7 +-
.../web/components/elements/SuggestionBox.tsx | 4 +-
packages/web/components/elements/Tooltip.tsx | 1 +
.../components/elements/images/ChromeIcon.tsx | 2 +-
.../components/elements/images/EdgeIcon.tsx | 2 +-
.../elements/images/FirefoxIcon.tsx | 2 +-
.../elements/images/OmnivoreFestiveLogo.tsx | 34 +-
.../elements/images/OmnivoreLogoBase.tsx | 39 +-
.../components/elements/images/SafariIcon.tsx | 2 +-
.../web/components/patterns/ArticleNotes.tsx | 4 +-
.../components/patterns/HighlightNotes.tsx | 2 +-
.../LibraryCards/LibraryHighlightGridCard.tsx | 6 +-
packages/web/components/templates/About.tsx | 9 +-
.../web/components/templates/ErrorLayout.tsx | 4 +-
.../web/components/templates/LoginForm.tsx | 40 +-
.../web/components/templates/LoginLayout.tsx | 41 +-
.../web/components/templates/SettingsMenu.tsx | 4 +-
.../web/components/templates/UploadModal.tsx | 2 +-
.../components/templates/article/Notebook.tsx | 2 +-
.../templates/article/NotebookModal.tsx | 4 +-
.../article/ReaderSettingsControl.tsx | 4 +-
.../components/templates/auth/EmailLogin.tsx | 6 +-
.../components/templates/auth/EmailSignup.tsx | 4 +-
.../templates/homeFeed/HighlightItem.tsx | 4 +-
.../templates/homeFeed/HighlightsLayout.tsx | 2 +-
.../templates/homeFeed/HomeFeedContainer.tsx | 2 +-
.../templates/homeFeed/LibraryFilterMenu.tsx | 4 +-
.../templates/integrations/Webhooks.tsx | 2 +-
.../templates/landing/LandingFooter.tsx | 26 +-
.../templates/landing/LandingHeader.tsx | 10 +-
.../templates/landing/LandingSection.tsx | 103 +-
.../landing/LandingSectionsContainer.tsx | 149 +-
.../web/components/tokens/stitches.config.ts | 2 +-
.../lib/highlights/normalizeHighlightRange.ts | 2 +-
packages/web/lib/highlights/useSelection.tsx | 2 +-
.../keyboardShortcuts/useKeyboardShortcuts.ts | 4 +-
packages/web/next.config.js | 3 +-
packages/web/package.json | 22 +-
packages/web/pages/about.tsx | 2 +-
packages/web/pages/api/save.ts | 11 +-
packages/web/pages/invite/[inviteCode].tsx | 180 ++-
packages/web/pages/settings/emails/index.tsx | 272 ++--
packages/web/pages/settings/subscriptions.tsx | 6 +-
.../landing/landing-00-hero.png} | Bin
.../landing/landing-01-save-it-now.png} | Bin
.../landing/landing-02-newsletters.png} | Bin
.../landing/landing-03-organisation.png} | Bin
.../landing-04-highlights-and-notes.png} | Bin
.../landing/landing-05-sync.png} | Bin
.../landing/landing-06-tts.png} | Bin
.../landing/landing-07-oss.png} | Bin
.../images/login/login-feature-image-full.png | Bin 0 -> 204315 bytes
.../images/login/login-feature-image-half.png | Bin 0 -> 409677 bytes
.../web/public/static/landing/landing-4.png | Bin 33723 -> 0 bytes
.../public/static/landing/landing-4@2x.png | Bin 33675 -> 0 bytes
.../static/landing/landingPage-02@1x.png | Bin 31732 -> 0 bytes
.../static/landing/landingPage-02@2x.png | Bin 90022 -> 0 bytes
.../static/landing/landingPage-02@3x.png | Bin 164336 -> 0 bytes
.../static/landing/landingPage-03@1x.png | Bin 119755 -> 0 bytes
.../static/landing/landingPage-03@3x.png | Bin 641538 -> 0 bytes
.../static/landing/landingPage-04@1x.png | Bin 28884 -> 0 bytes
.../static/landing/landingPage-04@3x.png | Bin 139675 -> 0 bytes
.../static/landing/landingPage-05@1x.png | Bin 40141 -> 0 bytes
.../static/landing/landingPage-05@3x.png | Bin 215017 -> 0 bytes
.../static/landing/landingPage-06@1x.png | Bin 63677 -> 0 bytes
.../static/landing/landingPage-06@3x.png | Bin 354276 -> 0 bytes
.../static/landing/landingPage-07@1x.png | Bin 49503 -> 0 bytes
.../static/landing/landingPage-07@3x.png | Bin 272583 -> 0 bytes
.../static/landing/landingPage-08@1x.png | Bin 142459 -> 0 bytes
.../static/landing/landingPage-08@3x.png | Bin 859328 -> 0 bytes
.../static/landing/landingPage-09@1x.png | Bin 156834 -> 0 bytes
.../static/landing/landingPage-09@3x.png | Bin 1005224 -> 0 bytes
.../static/landing/landingPage-5@2x.png | Bin 149096 -> 0 bytes
.../static/landing/landingPage-5@3x.png | Bin 292884 -> 0 bytes
.../static/landing/landingPage-feature@1x.png | Bin 69402 -> 0 bytes
.../static/landing/landingPage-feature@3x.png | Bin 380555 -> 0 bytes
packages/web/styles/globals.css | 7 +-
pkg/admin/package.json | 8 +-
pkg/extension/package.json | 3 +
yarn.lock | 1374 ++++++++++++++---
105 files changed, 1831 insertions(+), 780 deletions(-)
rename packages/web/public/static/{landing/landingPage-feature@2x.png => images/landing/landing-00-hero.png} (100%)
rename packages/web/public/static/{landing/landingPage-03@2x.png => images/landing/landing-01-save-it-now.png} (100%)
rename packages/web/public/static/{landing/landingPage-04@2x.png => images/landing/landing-02-newsletters.png} (100%)
rename packages/web/public/static/{landing/landingPage-05@2x.png => images/landing/landing-03-organisation.png} (100%)
rename packages/web/public/static/{landing/landingPage-06@2x.png => images/landing/landing-04-highlights-and-notes.png} (100%)
rename packages/web/public/static/{landing/landingPage-07@2x.png => images/landing/landing-05-sync.png} (100%)
rename packages/web/public/static/{landing/landingPage-08@2x.png => images/landing/landing-06-tts.png} (100%)
rename packages/web/public/static/{landing/landingPage-09@2x.png => images/landing/landing-07-oss.png} (100%)
create mode 100644 packages/web/public/static/images/login/login-feature-image-full.png
create mode 100644 packages/web/public/static/images/login/login-feature-image-half.png
delete mode 100644 packages/web/public/static/landing/landing-4.png
delete mode 100644 packages/web/public/static/landing/landing-4@2x.png
delete mode 100644 packages/web/public/static/landing/landingPage-02@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-02@2x.png
delete mode 100644 packages/web/public/static/landing/landingPage-02@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-03@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-03@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-04@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-04@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-05@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-05@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-06@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-06@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-07@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-07@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-08@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-08@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-09@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-09@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-5@2x.png
delete mode 100644 packages/web/public/static/landing/landingPage-5@3x.png
delete mode 100644 packages/web/public/static/landing/landingPage-feature@1x.png
delete mode 100644 packages/web/public/static/landing/landingPage-feature@3x.png
diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml
index 3c735a777..d98d51f1a 100644
--- a/.github/workflows/run-tests.yaml
+++ b/.github/workflows/run-tests.yaml
@@ -11,10 +11,16 @@ on:
paths-ignore:
- 'apple/**'
+env:
+ NEXT_PUBLIC_APP_ENV: prod
+ NEXT_PUBLIC_BASE_URL: http://localhost:3000
+ NEXT_PUBLIC_SERVER_BASE_URL: http://localhost:4000
+ NEXT_PUBLIC_HIGHLIGHTS_BASE_URL: http://localhost:3000
+
jobs:
run-code-tests:
name: Run Codebase tests
- runs-on: ubuntu-latest-m
+ runs-on: ${{ github.repository_owner == 'omnivore-app' && 'ubuntu-latest-m' || 'ubuntu-latest' }}
services:
postgres:
image: ankane/pgvector
@@ -71,6 +77,7 @@ jobs:
- name: TypeScript Build and Lint
run: |
source ~/.nvm/nvm.sh
+ env
yarn build
yarn lint
- name: Tests
diff --git a/.gitignore b/.gitignore
index ca9c3f95a..96a818d3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,5 @@ data.json
# android
*.aab
*.apk
+
+tsconfig.tsbuildinfo
diff --git a/apple/gql-server/package.json b/apple/gql-server/package.json
index 9088164b4..c6feb1a42 100644
--- a/apple/gql-server/package.json
+++ b/apple/gql-server/package.json
@@ -10,5 +10,8 @@
"express": "^4.18.1",
"express-graphql": "^0.12.0",
"graphql": "^16.8.1"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index d60fffe2f..aad1ec9a4 100644
--- a/package.json
+++ b/package.json
@@ -6,16 +6,16 @@
"workspaces": [
"packages/*"
],
- "license": "UNLICENSED",
+ "license": "AGPL-3.0-only",
"scripts": {
- "test": "lerna run --no-bail test --ignore @omnivore/web",
- "lint": "lerna run lint --ignore @omnivore/web",
- "build": "lerna run build --ignore @omnivore/web",
- "bootstrap": "lerna bootstrap",
+ "test": "lerna run --no-bail test",
+ "lint": "lerna run lint",
+ "build": "lerna run build",
"test:scoped:example": "lerna run test --scope={@omnivore/pdf-handler,@omnivore/web}",
"gql-typegen": "graphql-codegen",
"deploy:web": "vercel --prod"
},
+ "dependencies": {},
"devDependencies": {
"@ardatan/aggregate-error": "^0.0.6",
"@graphql-codegen/cli": "^2.6.2",
@@ -33,11 +33,10 @@
"graphql-tag": "^2.11.0",
"lerna": "^7.4.1",
"prettier": "^2.5.1",
- "typescript": "^4.4.3"
+ "typescript": "4.5.2"
},
"volta": {
"node": "18.16.1",
"yarn": "1.22.19"
- },
- "dependencies": {}
-}
\ No newline at end of file
+ }
+}
diff --git a/packages/api/package.json b/packages/api/package.json
index e2132082b..d4801f5ed 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -8,6 +8,7 @@
"start": "node dist/server.js",
"lint": "eslint src --ext ts,js,tsx,jsx",
"lint:fix": "eslint src --fix --ext ts,js,tsx,jsx",
+ "test:typecheck": "tsc --noEmit",
"test": "nyc mocha -r ts-node/register --config mocha-config.json --timeout 10000",
"copy-files": "copyfiles -u 1 src/**/*.html dist/"
},
@@ -145,7 +146,6 @@
"node": "18.16.1"
},
"volta": {
- "node": "18.16.1",
- "yarn": "1.22.19"
+ "extends": "../../package.json"
}
}
diff --git a/packages/appreader/package.json b/packages/appreader/package.json
index 00cf01662..7be7aa89a 100644
--- a/packages/appreader/package.json
+++ b/packages/appreader/package.json
@@ -32,7 +32,6 @@
"webpack-dev-server": "^4.7.4"
},
"volta": {
- "node": "18.16.0",
- "yarn": "1.22.10"
+ "extends": "../../package.json"
}
-}
\ No newline at end of file
+}
diff --git a/packages/appreader/webpack.config.ts b/packages/appreader/webpack.config.ts
index 472ab0d37..26579bb5b 100644
--- a/packages/appreader/webpack.config.ts
+++ b/packages/appreader/webpack.config.ts
@@ -60,6 +60,11 @@ const config: Configuration = {
],
resolve: {
extensions: ['.tsx', '.ts', '.js'],
+ fallback: {
+ stream: false,
+ fs: false,
+ zlib: false,
+ }
},
output: {
path: path.resolve(__dirname, 'build'),
diff --git a/packages/content-fetch/package.json b/packages/content-fetch/package.json
index 546552258..a0521cbee 100644
--- a/packages/content-fetch/package.json
+++ b/packages/content-fetch/package.json
@@ -20,5 +20,8 @@
"start_gcf": "npx functions-framework --port=9090 --target=puppeteer",
"start_preview": "npx functions-framework --target=preview",
"test": "mocha test/*.js"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/content-handler/package.json b/packages/content-handler/package.json
index adda03962..55ead0886 100644
--- a/packages/content-handler/package.json
+++ b/packages/content-handler/package.json
@@ -10,6 +10,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc"
@@ -38,5 +39,8 @@
"redis": "^4.3.1",
"underscore": "^1.13.6",
"uuid": "^9.0.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/content-handler/src/websites/twitter-handler.ts b/packages/content-handler/src/websites/twitter-handler.ts
index d80eaacf7..e8457c3d7 100644
--- a/packages/content-handler/src/websites/twitter-handler.ts
+++ b/packages/content-handler/src/websites/twitter-handler.ts
@@ -228,7 +228,7 @@ const getTweetIds = async (
timeout: 60000, // 60 seconds
})
- return (await page.evaluate(async (author) => {
+ return await page.evaluate(async (author) => {
/**
* Wait for `ms` amount of milliseconds
* @param {number} ms
@@ -278,7 +278,7 @@ const getTweetIds = async (
}
return ids
- }, author)) as string[]
+ }, author)
} catch (error) {
console.error('Error getting tweets', error)
diff --git a/packages/cypress/package.json b/packages/cypress/package.json
index 47d5818a8..cba74d085 100644
--- a/packages/cypress/package.json
+++ b/packages/cypress/package.json
@@ -11,7 +11,6 @@
},
"devDependencies": {},
"volta": {
- "node": "18.16.1",
- "yarn": "1.22.10"
+ "extends": "../../package.json"
}
-}
\ No newline at end of file
+}
diff --git a/packages/db/package.json b/packages/db/package.json
index fce36c4af..0af47351b 100644
--- a/packages/db/package.json
+++ b/packages/db/package.json
@@ -4,6 +4,7 @@
"description": "",
"scripts": {
"migrate": "ts-node ./migrate.ts",
+ "test:typecheck": "tsc --noEmit",
"generate": "plop"
},
"author": "",
diff --git a/packages/import-handler/package.json b/packages/import-handler/package.json
index 6d23478f2..0da52c021 100644
--- a/packages/import-handler/package.json
+++ b/packages/import-handler/package.json
@@ -10,6 +10,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc && yarn copy-files",
@@ -52,5 +53,8 @@
"unzip-stream": "^0.3.1",
"urlsafe-base64": "^1.0.0",
"uuid": "^9.0.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/inbound-email-handler/package.json b/packages/inbound-email-handler/package.json
index b8a2e4f78..0fa33a650 100644
--- a/packages/inbound-email-handler/package.json
+++ b/packages/inbound-email-handler/package.json
@@ -11,6 +11,7 @@
"keywords": [],
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -42,5 +43,8 @@
"parse-multipart-data": "^1.2.1",
"rfc2047": "^4.0.1",
"showdown": "^2.1.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/pdf-handler/package.json b/packages/pdf-handler/package.json
index 09af9e8c3..bd81243e8 100644
--- a/packages/pdf-handler/package.json
+++ b/packages/pdf-handler/package.json
@@ -11,6 +11,7 @@
"keywords": [],
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -33,5 +34,8 @@
"axios": "^0.27.2",
"concurrently": "^7.0.0",
"pdfjs-dist": "^2.9.359"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/puppeteer-parse/package.json b/packages/puppeteer-parse/package.json
index 306d905fe..db865b9ea 100644
--- a/packages/puppeteer-parse/package.json
+++ b/packages/puppeteer-parse/package.json
@@ -25,5 +25,8 @@
},
"scripts": {
"test": "mocha test/*.js"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/queue-manager/package.json b/packages/queue-manager/package.json
index 7c1319a45..28d59d34a 100644
--- a/packages/queue-manager/package.json
+++ b/packages/queue-manager/package.json
@@ -8,6 +8,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -28,5 +29,8 @@
"axios": "^1.4.0",
"dotenv": "^16.0.1",
"jsonwebtoken": "^8.5.1"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/readabilityjs/package.json b/packages/readabilityjs/package.json
index bcd6dc508..41c440cdc 100644
--- a/packages/readabilityjs/package.json
+++ b/packages/readabilityjs/package.json
@@ -41,5 +41,8 @@
"dependencies": {
"html-entities": "^2.3.2",
"parse-srcset": "^1.0.2"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/rss-handler/package.json b/packages/rss-handler/package.json
index 0db5d93fd..af647811e 100644
--- a/packages/rss-handler/package.json
+++ b/packages/rss-handler/package.json
@@ -8,6 +8,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -28,5 +29,8 @@
"dotenv": "^16.0.1",
"jsonwebtoken": "^8.5.1",
"rss-parser": "^3.13.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/rule-handler/package.json b/packages/rule-handler/package.json
index b9eadc9c4..5d722480b 100644
--- a/packages/rule-handler/package.json
+++ b/packages/rule-handler/package.json
@@ -8,6 +8,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -26,5 +27,8 @@
"dotenv": "^16.0.1",
"jsonwebtoken": "^8.5.1",
"search-query-parser": "^1.6.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/text-to-speech/package.json b/packages/text-to-speech/package.json
index a1536e0b1..3047e6fd3 100644
--- a/packages/text-to-speech/package.json
+++ b/packages/text-to-speech/package.json
@@ -11,6 +11,7 @@
"keywords": [],
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -45,5 +46,8 @@
"natural": "^6.2.0",
"redis": "^4.3.1",
"underscore": "^1.13.4"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/thumbnail-handler/package.json b/packages/thumbnail-handler/package.json
index f6ac4e080..707c36ae7 100644
--- a/packages/thumbnail-handler/package.json
+++ b/packages/thumbnail-handler/package.json
@@ -8,6 +8,7 @@
"license": "Apache-2.0",
"scripts": {
"test": "yarn mocha -r ts-node/register --config mocha-config.json",
+ "test:typecheck": "tsc --noEmit",
"lint": "eslint src --ext ts,js,tsx,jsx",
"compile": "tsc",
"build": "tsc",
@@ -30,5 +31,8 @@
"jsonwebtoken": "^8.5.1",
"linkedom": "^0.14.26",
"urlsafe-base64": "^1.0.0"
+ },
+ "volta": {
+ "extends": "../../package.json"
}
}
diff --git a/packages/web/components/elements/Button.tsx b/packages/web/components/elements/Button.tsx
index 2939850cf..506fd869b 100644
--- a/packages/web/components/elements/Button.tsx
+++ b/packages/web/components/elements/Button.tsx
@@ -28,11 +28,9 @@ export const Button = styled('button', {
color: '#3D3D3D',
bg: '#FFEA9F',
p: '10px 15px',
- '&:hover': {
+ '&:hover, &:focus': {
bg: '$omnivoreCtaYellow',
- },
- '&:focus': {
- border: '1px solid $omnivoreCtaYellow',
+ outline: '1px solid $omnivoreCtaYellow',
},
},
cancelGeneric: {
@@ -45,18 +43,13 @@ export const Button = styled('button', {
border: '1px solid transparent',
p: '10px 15px',
bg: 'transparent',
- '&:hover': {
+ '&:hover, &:focus': {
bg: '#EBEBEB',
- },
- '&:focus': {
- outline: 'none !important',
- border: '1px solid $omnivoreCtaYellow',
+ outline: '1px solid $omnivoreCtaYellow',
},
},
ctaOutlineYellow: {
boxSizing: 'border-box',
- '-moz-box-sizing': 'border-box',
- '-webkit-box-sizing': 'border-box',
borderColor: 'unset',
border: '1px solid $omnivoreCtaYellow',
fontSize: '14px',
@@ -159,7 +152,6 @@ export const Button = styled('button', {
outlineColor: 'rgba(0, 0, 0, 0)',
border: '1px solid rgba(0, 0, 0, 0.06)',
cursor: 'pointer',
- '&:focus': { outline: 'none' },
},
ctaModal: {
height: '32px',
@@ -172,7 +164,6 @@ export const Button = styled('button', {
border: '1px solid $grayBorder',
cursor: 'pointer',
borderRadius: '8px',
- '&:focus': { outline: 'none' },
},
ctaSecondary: {
color: '$grayText',
@@ -245,7 +236,6 @@ export const Button = styled('button', {
'&:hover': {
opacity: 0.7,
},
- '&:focus': { outline: 'none' },
},
highlightBarIcon: {
p: '0px',
@@ -257,7 +247,6 @@ export const Button = styled('button', {
opacity: 0.5,
},
- '&:focus': { outline: 'none' },
},
articleActionIcon: {
bg: 'transparent',
diff --git a/packages/web/components/elements/HeaderNavLink.tsx b/packages/web/components/elements/HeaderNavLink.tsx
index 149253bb5..0db02fa95 100644
--- a/packages/web/components/elements/HeaderNavLink.tsx
+++ b/packages/web/components/elements/HeaderNavLink.tsx
@@ -11,37 +11,35 @@ type HeaderNavLinkProps = {
export function HeaderNavLink(props: HeaderNavLinkProps): JSX.Element {
return (
-
-
-
+
+ {props.text}
+
- {props.text}
-
-
-
+ />
+
)
}
diff --git a/packages/web/components/elements/LabelColorDropdown.tsx b/packages/web/components/elements/LabelColorDropdown.tsx
index 69d7a79e9..3fc4d6fd5 100644
--- a/packages/web/components/elements/LabelColorDropdown.tsx
+++ b/packages/web/components/elements/LabelColorDropdown.tsx
@@ -1,4 +1,4 @@
-import React, { useRef, useState } from 'react'
+import { useRef, useState } from 'react'
import { styled } from '../tokens/stitches.config'
import { Box, HStack } from './LayoutPrimitives'
import { StyledText } from './StyledText'
@@ -6,9 +6,14 @@ import {
LabelColorDropdownProps,
LabelOptionProps,
} from '../../utils/settings-page/labels/types'
-import { TwitterPicker } from 'react-color'
+import { TwitterPicker as TwitterPicker_, TwitterPickerProps } from 'react-color'
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
+// TwitterPicker is a Class component, but the types are broken in React 18.
+// TODO: Maybe move away from this component, since it hasn't been updated for 3 years.
+// https://github.com/casesandberg/react-color/issues/883
+const TwitterPicker = TwitterPicker_ as unknown as React.FunctionComponent
+
const DropdownMenuContent = styled(DropdownMenuPrimitive.Content, {
borderRadius: 6,
backgroundColor: '$grayBg',
diff --git a/packages/web/components/elements/LabelsPicker.tsx b/packages/web/components/elements/LabelsPicker.tsx
index b234923e6..3aac0a1eb 100644
--- a/packages/web/components/elements/LabelsPicker.tsx
+++ b/packages/web/components/elements/LabelsPicker.tsx
@@ -1,4 +1,4 @@
-import AutosizeInput from 'react-input-autosize'
+import AutosizeInput_, { AutosizeInputProps } from 'react-input-autosize'
import { Box, SpanBox } from './LayoutPrimitives'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Label } from '../../lib/networking/fragments/labelFragment'
@@ -8,6 +8,11 @@ import { EditLabelChip } from './EditLabelChip'
import { LabelsDispatcher } from '../../lib/hooks/useSetPageLabels'
import { EditLabelChipStack } from './EditLabelChipStack'
+// AutosizeInput is a Class component, but the types are broken in React 18.
+// TODO: Maybe move away from this component, since it hasn't been updated for 3 years.
+// https://github.com/JedWatson/react-input-autosize/issues
+const AutosizeInput = AutosizeInput_ as unknown as React.FunctionComponent
+
const MaxUnstackedLabels = 7
type LabelsPickerProps = {
diff --git a/packages/web/components/elements/SuggestionBox.tsx b/packages/web/components/elements/SuggestionBox.tsx
index fd01bf44d..5118708af 100644
--- a/packages/web/components/elements/SuggestionBox.tsx
+++ b/packages/web/components/elements/SuggestionBox.tsx
@@ -40,14 +40,14 @@ const InternalOrExternalLink = (props: InternalOrExternalLinkProps) => {
}}
>
{!isExternal ? (
- {props.children}
+ {props.children}
) : (
{props.children}
)}
- )
+ );
}
export const SuggestionBox = (props: SuggestionBoxProps) => {
diff --git a/packages/web/components/elements/Tooltip.tsx b/packages/web/components/elements/Tooltip.tsx
index b1139061a..69ff37a38 100644
--- a/packages/web/components/elements/Tooltip.tsx
+++ b/packages/web/components/elements/Tooltip.tsx
@@ -53,6 +53,7 @@ export const TooltipContent = StyledContent
export const TooltipArrow = StyledArrow
type TooltipWrappedProps = {
+ children: React.ReactNode;
tooltipContent: string;
active?: boolean;
tooltipSide?: TooltipPrimitive.TooltipContentProps['side']
diff --git a/packages/web/components/elements/images/ChromeIcon.tsx b/packages/web/components/elements/images/ChromeIcon.tsx
index 2b803e63b..2619c7be6 100644
--- a/packages/web/components/elements/images/ChromeIcon.tsx
+++ b/packages/web/components/elements/images/ChromeIcon.tsx
@@ -1,5 +1,5 @@
import Image from 'next/image'
export function ChromeIcon(): JSX.Element {
- return
+ return
}
diff --git a/packages/web/components/elements/images/EdgeIcon.tsx b/packages/web/components/elements/images/EdgeIcon.tsx
index 783ca59a5..8bee568ed 100644
--- a/packages/web/components/elements/images/EdgeIcon.tsx
+++ b/packages/web/components/elements/images/EdgeIcon.tsx
@@ -1,5 +1,5 @@
import Image from 'next/image'
export function EdgeIcon(): JSX.Element {
- return
+ return
}
diff --git a/packages/web/components/elements/images/FirefoxIcon.tsx b/packages/web/components/elements/images/FirefoxIcon.tsx
index baeb4f83b..5775596d2 100644
--- a/packages/web/components/elements/images/FirefoxIcon.tsx
+++ b/packages/web/components/elements/images/FirefoxIcon.tsx
@@ -1,5 +1,5 @@
import Image from 'next/image'
export function FirefoxIcon(): JSX.Element {
- return
+ return
}
diff --git a/packages/web/components/elements/images/OmnivoreFestiveLogo.tsx b/packages/web/components/elements/images/OmnivoreFestiveLogo.tsx
index aca045d1e..a294b7970 100644
--- a/packages/web/components/elements/images/OmnivoreFestiveLogo.tsx
+++ b/packages/web/components/elements/images/OmnivoreFestiveLogo.tsx
@@ -14,20 +14,22 @@ export function OmnivoreFestiveLogo(
const href = props.href || '/home'
return (
-
-
-
-
-
- )
+ (
+
+
+
+ )
+ );
}
diff --git a/packages/web/components/elements/images/OmnivoreLogoBase.tsx b/packages/web/components/elements/images/OmnivoreLogoBase.tsx
index ecbce303e..ad827f9a8 100644
--- a/packages/web/components/elements/images/OmnivoreLogoBase.tsx
+++ b/packages/web/components/elements/images/OmnivoreLogoBase.tsx
@@ -1,8 +1,5 @@
import Link from 'next/link'
import { useRouter } from 'next/router'
-import { ReactChildren } from 'react'
-import { config } from '../../tokens/stitches.config'
-
export type OmnivoreLogoBaseProps = {
color?: string
href?: string
@@ -15,23 +12,25 @@ export function OmnivoreLogoBase(props: OmnivoreLogoBaseProps): JSX.Element {
const router = useRouter()
return (
-
- {
- const query = window.sessionStorage.getItem('q')
- if (query) {
- router.push(`/home?${query}`)
- event.preventDefault()
- }
- }}
- >
- {props.children}
-
+ {
+ const query = window.sessionStorage.getItem('q')
+ if (query) {
+ router.push(`/home?${query}`)
+ event.preventDefault()
+ }
+ }}
+ tabIndex={-1}
+ aria-label="Omnivore logo"
+ >
+ {props.children}
)
}
diff --git a/packages/web/components/elements/images/SafariIcon.tsx b/packages/web/components/elements/images/SafariIcon.tsx
index a8187fc89..e14b598a0 100644
--- a/packages/web/components/elements/images/SafariIcon.tsx
+++ b/packages/web/components/elements/images/SafariIcon.tsx
@@ -1,5 +1,5 @@
import Image from 'next/image'
export function SafariIcon(): JSX.Element {
- return
+ return
}
diff --git a/packages/web/components/patterns/ArticleNotes.tsx b/packages/web/components/patterns/ArticleNotes.tsx
index a4a786b99..5b62ba91e 100644
--- a/packages/web/components/patterns/ArticleNotes.tsx
+++ b/packages/web/components/patterns/ArticleNotes.tsx
@@ -40,7 +40,7 @@ type NoteSectionProps = {
export function ArticleNotes(props: NoteSectionProps): JSX.Element {
const saveText = useCallback(
- (text) => {
+ (text: string) => {
props.saveText(text)
},
[props]
@@ -78,7 +78,7 @@ export function HighlightViewNote(props: HighlightViewNoteProps): JSX.Element {
const [lastSaved, setLastSaved] = useState(undefined)
const saveText = useCallback(
- (text) => {
+ (text: string) => {
;(async () => {
const success = await updateHighlightMutation({
annotation: text,
diff --git a/packages/web/components/patterns/HighlightNotes.tsx b/packages/web/components/patterns/HighlightNotes.tsx
index 253caa3d3..076354018 100644
--- a/packages/web/components/patterns/HighlightNotes.tsx
+++ b/packages/web/components/patterns/HighlightNotes.tsx
@@ -48,7 +48,7 @@ export function HighlightViewNote(props: HighlightViewNoteProps): JSX.Element {
const [errorSaving, setErrorSaving] = useState(undefined)
const saveText = useCallback(
- (text, updateTime, interactive) => {
+ (text: string, updateTime: Date, interactive: boolean) => {
;(async () => {
const success = await updateHighlightMutation({
annotation: text,
diff --git a/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx
index d3ee8a620..0ad21d885 100644
--- a/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx
+++ b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx
@@ -30,10 +30,10 @@ export function LibraryHighlightGridCard(
props: LibraryHighlightGridCardProps
): JSX.Element {
const [expanded, setExpanded] = useState(false)
- const higlightCount = props.item.highlights?.length ?? 0
+ const highlightCount = props.item.highlights?.length ?? 0
const router = useRouter()
const viewInReader = useCallback(
- (highlightId) => {
+ (highlightId: string) => {
if (!router || !router.isReady || !props.viewer) {
showErrorToast('Error navigating to highlight')
return
@@ -197,7 +197,7 @@ export function LibraryHighlightGridCard(
event.preventDefault()
}}
>
- {`View ${higlightCount} highlight${higlightCount > 1 ? 's' : ''}`}
+ {`View ${highlightCount} highlight${highlightCount > 1 ? 's' : ''}`}
@@ -49,9 +50,11 @@ export function About(props: AboutProps): JSX.Element {
readers.`}
diff --git a/packages/web/components/templates/ErrorLayout.tsx b/packages/web/components/templates/ErrorLayout.tsx
index b3370b928..be97b9c20 100644
--- a/packages/web/components/templates/ErrorLayout.tsx
+++ b/packages/web/components/templates/ErrorLayout.tsx
@@ -32,11 +32,11 @@ export function ErrorLayout(props: ErrorLayoutProps): JSX.Element {
-
+
- )
+ );
}
diff --git a/packages/web/components/templates/LoginForm.tsx b/packages/web/components/templates/LoginForm.tsx
index c6f49e661..ed475a012 100644
--- a/packages/web/components/templates/LoginForm.tsx
+++ b/packages/web/components/templates/LoginForm.tsx
@@ -50,21 +50,21 @@ export function LoginForm(props: LoginFormProps): JSX.Element {
>
Save articles and read them later in our distraction-free reader.
-
-
-
- Learn More ->
-
-
+
+
+
+ Learn More ->
+
+
@@ -103,7 +103,7 @@ export function LoginForm(props: LoginFormProps): JSX.Element {
/>
)}
-
+
- )
+ );
}
function GoogleAuthButton() {
@@ -154,17 +154,17 @@ export function TermAndConditionsFooter(): JSX.Element {
}}
>
By signing up, you agree to Omnivore’s{' '}
-
+
Terms of Service
{' '}
and{' '}
-
+
Privacy Policy
- )
+ );
}
diff --git a/packages/web/components/templates/LoginLayout.tsx b/packages/web/components/templates/LoginLayout.tsx
index 4c6bbe82a..a495047a1 100644
--- a/packages/web/components/templates/LoginLayout.tsx
+++ b/packages/web/components/templates/LoginLayout.tsx
@@ -1,3 +1,4 @@
+import { unstable_getImgProps as getImgProps } from 'next/image'
import {
Box,
HStack,
@@ -9,6 +10,9 @@ import type { LoginFormProps } from './LoginForm'
import { OmnivoreNameLogo } from '../elements/images/OmnivoreNameLogo'
import { theme } from '../tokens/stitches.config'
+import featureFullWidthImage from '../../public/static/images/login/login-feature-image-full.png'
+import featureHalfWidthImage from '../../public/static/images/login/login-feature-image-half.png'
+
export function LoginLayout(props: LoginFormProps): JSX.Element {
return (
<>
@@ -86,7 +90,30 @@ function MediumLoginLayout(props: LoginFormProps) {
)
}
+const srcSetToImageSet = (srcFallback: string, srcSet?: string): string => {
+ if (!srcSet) return `url(${srcFallback})`
+
+ return `image-set( ${srcSet
+ .split(', ')
+ .map((subSrc) => {
+ const [src, resolution] = subSrc.split(' ')
+ return `url("${decodeURIComponent(src)}") ${resolution}`
+ })
+ .join(',')}
+)`
+}
+
function OmnivoreIllustration() {
+ const { props: halfWidthImgProps } = getImgProps({
+ src: featureHalfWidthImage,
+ alt: '',
+ })
+
+ const { props: fullWidthImgProps } = getImgProps({
+ src: featureFullWidthImage,
+ alt: '',
+ })
+
return (
)
diff --git a/packages/web/components/templates/SettingsMenu.tsx b/packages/web/components/templates/SettingsMenu.tsx
index 7789f960a..cfe9d60c1 100644
--- a/packages/web/components/templates/SettingsMenu.tsx
+++ b/packages/web/components/templates/SettingsMenu.tsx
@@ -204,7 +204,7 @@ function SettingsButton(props: SettingsButtonProps): JSX.Element {
}, [props, router])
return (
-
+
- )
+ );
}
diff --git a/packages/web/components/templates/UploadModal.tsx b/packages/web/components/templates/UploadModal.tsx
index ec8b296c1..f6a2c605f 100644
--- a/packages/web/components/templates/UploadModal.tsx
+++ b/packages/web/components/templates/UploadModal.tsx
@@ -110,7 +110,7 @@ export function UploadModal(props: UploadModalProps): JSX.Element {
const dropzoneRef = useRef(null)
const openDialog = useCallback(
- (event) => {
+ (event: React.MouseEvent) => {
if (dropzoneRef.current) {
dropzoneRef.current.open()
}
diff --git a/packages/web/components/templates/article/Notebook.tsx b/packages/web/components/templates/article/Notebook.tsx
index 21ae2abdb..06b3e370e 100644
--- a/packages/web/components/templates/article/Notebook.tsx
+++ b/packages/web/components/templates/article/Notebook.tsx
@@ -163,7 +163,7 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
}, [highlights])
const handleSaveNoteText = useCallback(
- (text) => {
+ (text: string) => {
const changeTime = new Date()
setLastChanged(changeTime)
diff --git a/packages/web/components/templates/article/NotebookModal.tsx b/packages/web/components/templates/article/NotebookModal.tsx
index 55205f6be..aefbe20ba 100644
--- a/packages/web/components/templates/article/NotebookModal.tsx
+++ b/packages/web/components/templates/article/NotebookModal.tsx
@@ -49,7 +49,7 @@ export function NotebookModal(props: NotebookModalProps): JSX.Element {
props.onClose(allAnnotations ?? [], deletedHighlights ?? [])
}, [props, allAnnotations])
- const handleAnnotationsChange = useCallback((allAnnotations) => {
+ const handleAnnotationsChange = useCallback((allAnnotations: Highlight[]) => {
setAllAnnotations(allAnnotations)
}, [])
@@ -66,7 +66,7 @@ export function NotebookModal(props: NotebookModalProps): JSX.Element {
}, [allAnnotations])
const viewInReader = useCallback(
- (highlightId) => {
+ (highlightId: string) => {
props.viewHighlightInReader(highlightId)
handleClose()
},
diff --git a/packages/web/components/templates/article/ReaderSettingsControl.tsx b/packages/web/components/templates/article/ReaderSettingsControl.tsx
index 322fa2194..cc6c034a3 100644
--- a/packages/web/components/templates/article/ReaderSettingsControl.tsx
+++ b/packages/web/components/templates/article/ReaderSettingsControl.tsx
@@ -292,7 +292,7 @@ function FontControls(props: FontControlsProps): JSX.Element {
})
const handleFontSizeChange = useCallback(
- (value) => {
+ (value: number) => {
readerSettings.actionHandler('setFontSize', value)
},
[readerSettings]
@@ -399,7 +399,7 @@ function LayoutControls(props: LayoutControlsProps): JSX.Element {
const { readerSettings } = props
const handleMarginWidthChange = useCallback(
- (value) => {
+ (value: number) => {
readerSettings.setMarginWidth(value)
},
[readerSettings]
diff --git a/packages/web/components/templates/auth/EmailLogin.tsx b/packages/web/components/templates/auth/EmailLogin.tsx
index a7c31950b..62fc4847d 100644
--- a/packages/web/components/templates/auth/EmailLogin.tsx
+++ b/packages/web/components/templates/auth/EmailLogin.tsx
@@ -122,7 +122,7 @@ export function EmailLogin(): JSX.Element {
}}
>
Don't have an account?{' '}
-
+
Sign up
@@ -140,7 +140,7 @@ export function EmailLogin(): JSX.Element {
}}
>
Forgot your password?{' '}
-
+
Click here
@@ -148,5 +148,5 @@ export function EmailLogin(): JSX.Element {
- )
+ );
}
diff --git a/packages/web/components/templates/auth/EmailSignup.tsx b/packages/web/components/templates/auth/EmailSignup.tsx
index d3becc8ec..e23a5f584 100644
--- a/packages/web/components/templates/auth/EmailSignup.tsx
+++ b/packages/web/components/templates/auth/EmailSignup.tsx
@@ -206,7 +206,7 @@ export function EmailSignup(): JSX.Element {
}}
>
Already have an account?{' '}
-
+
Login instead
@@ -215,5 +215,5 @@ export function EmailSignup(): JSX.Element {
- )
+ );
}
diff --git a/packages/web/components/templates/homeFeed/HighlightItem.tsx b/packages/web/components/templates/homeFeed/HighlightItem.tsx
index 4aa97911e..b98f8a7c0 100644
--- a/packages/web/components/templates/homeFeed/HighlightItem.tsx
+++ b/packages/web/components/templates/homeFeed/HighlightItem.tsx
@@ -108,7 +108,7 @@ export function HighlightsMenu(props: HighlightsMenuProps): JSX.Element {
+ legacyBehavior>
{
console.log('event.ctrlKey: ', event.ctrlKey, event.metaKey)
@@ -129,7 +129,7 @@ export function HighlightsMenu(props: HighlightsMenuProps): JSX.Element {
- )
+ );
}
const sortHighlights = (highlights: Highlight[]) => {
diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx
index d0260dd75..75ffcf5d0 100644
--- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx
+++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx
@@ -368,7 +368,7 @@ function HighlightList(props: HighlightListProps): JSX.Element {
}, [props.item.node.highlights])
const viewInReader = useCallback(
- (highlightId) => {
+ (highlightId: string) => {
if (!router || !router.isReady || !props.viewer) {
showErrorToast('Error navigating to highlight')
return
diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
index fa8476091..45dd10655 100644
--- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
+++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
@@ -351,7 +351,7 @@ export function HomeFeedContainer(): JSX.Element {
}, [libraryItems, activeCardId])
const getItem = useCallback(
- (itemId) => {
+ (itemId: string) => {
return libraryItems.find((item) => item.node.id === itemId)
},
[libraryItems]
diff --git a/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx b/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
index fba2015c9..6fb5a6a2f 100644
--- a/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
+++ b/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
@@ -553,7 +553,7 @@ type EditButtonProps = {
function EditButton(props: EditButtonProps): JSX.Element {
return (
-
+
- )
+ );
}
diff --git a/packages/web/components/templates/integrations/Webhooks.tsx b/packages/web/components/templates/integrations/Webhooks.tsx
index d36ab8a64..ce8bcd95e 100644
--- a/packages/web/components/templates/integrations/Webhooks.tsx
+++ b/packages/web/components/templates/integrations/Webhooks.tsx
@@ -140,7 +140,7 @@ export function Webhooks(): JSX.Element {
}}
>
{item.method}
- {item.createdAt}
+ {item.createdAt?.toLocaleDateString()}
)
diff --git a/packages/web/components/templates/landing/LandingFooter.tsx b/packages/web/components/templates/landing/LandingFooter.tsx
index 71920855f..66e682148 100644
--- a/packages/web/components/templates/landing/LandingFooter.tsx
+++ b/packages/web/components/templates/landing/LandingFooter.tsx
@@ -1,4 +1,4 @@
-import { HStack, VStack } from '../../elements/LayoutPrimitives'
+import { Box, HStack, VStack } from '../../elements/LayoutPrimitives'
import { styled } from '../../tokens/stitches.config'
import { StyledText } from '../../elements/StyledText'
@@ -30,11 +30,29 @@ export function LandingFooter(): JSX.Element {
textDecoration: 'underline',
},
},
+ '@mdDown': {
+ columns: 2,
+ width: '100%',
+ marginTop: "8px",
+ marginBottom: "30px",
+ },
})
return (
-
+
Install
@@ -77,7 +95,7 @@ export function LandingFooter(): JSX.Element {
- Contact us via email
+ Contact us via email
@@ -112,7 +130,7 @@ export function LandingFooter(): JSX.Element {
-
+
)
}
diff --git a/packages/web/components/templates/landing/LandingHeader.tsx b/packages/web/components/templates/landing/LandingHeader.tsx
index 2d30cde14..5f91bf821 100644
--- a/packages/web/components/templates/landing/LandingHeader.tsx
+++ b/packages/web/components/templates/landing/LandingHeader.tsx
@@ -1,16 +1,18 @@
import { Box } from '../../elements/LayoutPrimitives'
import { OmnivoreNameLogo } from '../../elements/images/OmnivoreNameLogo'
import { Button } from '../../elements/Button'
+import Link from 'next/link'
const LoginButton = (): JSX.Element => {
return (
}
+ descriptionText={section[props.lang].descriptionText}
+ imagePosition={sectionIndex % 2 ? 'left' : 'right'}
image={
-
}
/>
)
})}
-
+
{props.lang == 'en' && (
- Get Started With Omnivore Today
+
+ Get Started With Omnivore Today
+
)}
diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts
index dbd792a7f..675675951 100644
--- a/packages/web/components/tokens/stitches.config.ts
+++ b/packages/web/components/tokens/stitches.config.ts
@@ -269,7 +269,7 @@ const darkThemeSpec = {
labelButtonsBg: '#5F5E58',
- // New theme, special naming to keep things straigh
+ // New theme, special naming to keep things straight
// once all switch over, we will rename
// DARK
colorScheme: 'dark',
diff --git a/packages/web/lib/highlights/normalizeHighlightRange.ts b/packages/web/lib/highlights/normalizeHighlightRange.ts
index d9c207398..d419750a6 100644
--- a/packages/web/lib/highlights/normalizeHighlightRange.ts
+++ b/packages/web/lib/highlights/normalizeHighlightRange.ts
@@ -23,7 +23,7 @@ function disableWordSnap(str: string): boolean {
}
const isWhitespace = (c?: string): boolean => {
- return !!c && /\u2014|\u2013|,|\s/.test(c)
+ return !!c && /\u2014|\u2013|,|\s/.test(c);
}
function findNextWord(
diff --git a/packages/web/lib/highlights/useSelection.tsx b/packages/web/lib/highlights/useSelection.tsx
index 6ad361a6f..fcb02d0dc 100644
--- a/packages/web/lib/highlights/useSelection.tsx
+++ b/packages/web/lib/highlights/useSelection.tsx
@@ -25,7 +25,7 @@ export function useSelection(
)
const handleFinishTouch = useCallback(
- async (mouseEvent) => {
+ async (mouseEvent: any) => {
let wasDragEvent = false
const tapAttributes = {
tapX: mouseEvent.clientX,
diff --git a/packages/web/lib/keyboardShortcuts/useKeyboardShortcuts.ts b/packages/web/lib/keyboardShortcuts/useKeyboardShortcuts.ts
index 1ac8dfa67..c91c65a8e 100644
--- a/packages/web/lib/keyboardShortcuts/useKeyboardShortcuts.ts
+++ b/packages/web/lib/keyboardShortcuts/useKeyboardShortcuts.ts
@@ -105,7 +105,7 @@ export const useKeyboardShortcuts = (commands: KeyboardCommand[]): void => {
)
const keydownListener = useCallback(
- (keydownEvent) => {
+ (keydownEvent: any) => {
const { target } = keydownEvent
if (!keydownEvent.key) return
const key = keydownEvent.key.toLowerCase()
@@ -129,7 +129,7 @@ export const useKeyboardShortcuts = (commands: KeyboardCommand[]): void => {
)
const keyupListener = useCallback(
- (keyupEvent) => {
+ (keyupEvent: any) => {
if (!keyupEvent.key) return
const key = keyupEvent.key.toLowerCase()
if (keys[key] === undefined) return
diff --git a/packages/web/next.config.js b/packages/web/next.config.js
index 2c8b8d32a..7718cdec9 100644
--- a/packages/web/next.config.js
+++ b/packages/web/next.config.js
@@ -17,6 +17,7 @@ const ContentSecurityPolicy = `
const moduleExports = {
images: {
+ formats: ['image/avif', 'image/webp'],
domains: [
'proxy-demo.omnivore-image-cache.app',
'proxy-dev.omnivore-image-cache.app',
@@ -56,7 +57,7 @@ const moduleExports = {
},
],
},
- ]
+ ];
},
async redirects() {
return [
diff --git a/packages/web/package.json b/packages/web/package.json
index a5bca6693..9fdcbec84 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -13,6 +13,7 @@
"test": "jest",
"test:watch": "jest --watch",
"test:build": "jest && next build",
+ "test:typecheck": "tsc --noEmit",
"upgrade-psdpdfkit": "cp -R '../../node_modules/pspdfkit/dist/pspdfkit-lib' public/pspdfkit-lib",
"storybook": "start-storybook -p 6006 -s ./public",
"build-storybook": "build-storybook -s public"
@@ -32,7 +33,6 @@
"@radix-ui/react-tooltip": "^0.1.7",
"@sentry/nextjs": "^7.42.0",
"@stitches/react": "^1.2.5",
- "@types/react-input-autosize": "^2.2.1",
"antd": "4.24.3",
"axios": "^1.2.0",
"color2k": "^2.0.0",
@@ -47,16 +47,16 @@
"markdown-it": "^13.0.1",
"match-sorter": "^6.3.1",
"nanoid": "^3.1.29",
- "next": "^12.1.0",
+ "next": "^13.5.6",
"node-html-markdown": "^1.3.0",
"papaparse": "^5.4.1",
"phosphor-react": "^1.4.0",
"posthog-js": "^1.78.2",
"pspdfkit": "^2022.2.3",
- "react": "^17.0.2",
+ "react": "^18.2.0",
"react-color": "^2.19.3",
"react-colorful": "^5.5.1",
- "react-dom": "^17.0.2",
+ "react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-hot-toast": "^2.1.1",
"react-input-autosize": "^3.0.0",
@@ -68,6 +68,7 @@
"react-super-responsive-table": "^5.2.1",
"react-topbar-progress-indicator": "^4.1.1",
"remark-gfm": "^3.0.1",
+ "sharp": "^0.32.6",
"swr": "^1.0.1",
"uuid": "^8.3.2",
"yet-another-react-lightbox": "^3.12.0"
@@ -93,14 +94,14 @@
"@types/lodash.debounce": "^4.0.6",
"@types/markdown-it": "^12.2.3",
"@types/papaparse": "^5.3.7",
- "@types/react": "17.0.2",
- "@types/react-color": "^3.0.6",
- "@types/react-dom": "^17.0.2",
+ "@types/react": "^18.2.0",
+ "@types/react-color": "^3.0.9",
+ "@types/react-dom": "^18.2.0",
"@types/react-input-autosize": "^2.2.1",
"@types/uuid": "^8.3.1",
"babel-jest": "^27.4.5",
"babel-loader": "^8.2.3",
- "eslint-config-next": "12.0.7",
+ "eslint-config-next": "^13.5.6",
"eslint-plugin-functional": "^4.0.2",
"eslint-plugin-react": "^7.28.0",
"graphql": "^15.6.1",
@@ -108,7 +109,6 @@
"storybook-addon-next-router": "^3.1.1"
},
"volta": {
- "node": "18.16.1",
- "yarn": "1.22.10"
+ "extends": "../../package.json"
}
-}
\ No newline at end of file
+}
diff --git a/packages/web/pages/about.tsx b/packages/web/pages/about.tsx
index 0373cac24..585ff22df 100644
--- a/packages/web/pages/about.tsx
+++ b/packages/web/pages/about.tsx
@@ -11,7 +11,7 @@ export default function LandingPage(): JSX.Element {
description="Omnivore is the free, open source, read-it-later app for serious readers."
/>
-
+
>
)
}
diff --git a/packages/web/pages/api/save.ts b/packages/web/pages/api/save.ts
index 556b674d5..bfcceb563 100644
--- a/packages/web/pages/api/save.ts
+++ b/packages/web/pages/api/save.ts
@@ -4,8 +4,11 @@ import { locale, timeZone } from '../../lib/dateFormatting'
import { SaveResponseData } from '../../lib/networking/mutations/saveUrlMutation'
import { ssrFetcher } from '../../lib/networking/networkHelpers'
+type Request = NextApiRequest & { cookies: { [key: string]: string } }
+type Response = NextApiResponse
+
const saveUrl = async (
- req: NextApiRequest,
+ req: Request,
url: URL,
labels: string[] | undefined,
state: string | undefined,
@@ -53,11 +56,7 @@ const saveUrl = async (
}
}
-// eslint-disable-next-line import/no-anonymous-default-export
-export default async (
- req: NextApiRequest,
- res: NextApiResponse
-): Promise => {
+export default async function handler(req: Request, res: Response) {
const urlStr = req.query['url']
if (req.query['labels'] && typeof req.query['labels'] === 'string') {
req.query['labels'] = [req.query['labels']]
diff --git a/packages/web/pages/invite/[inviteCode].tsx b/packages/web/pages/invite/[inviteCode].tsx
index c95a7365d..fb37901bf 100644
--- a/packages/web/pages/invite/[inviteCode].tsx
+++ b/packages/web/pages/invite/[inviteCode].tsx
@@ -32,7 +32,7 @@ export default function InvitePage(): JSX.Element {
}, [isLoading, router, viewerData, viewerDataError])
const acceptClicked = useCallback(
- (event) => {
+ (event: any) => {
event?.stopPropagation()
if (!router.isReady) {
@@ -63,108 +63,106 @@ export default function InvitePage(): JSX.Element {
[router, inviteCode]
)
- return (
- <>
-
-
-
+
+
+
+
+ You're invited
+
+
+
-
- You're invited
-
-
+ You have been invited to join a recommendation group on Omnivore.
+ Recommendation groups allow you to share articles with other group
+ members.
+
+ {errorMessage && (
- You have been invited to join a recommendation group on Omnivore.
- Recommendation groups allow you to share articles with other group
- members.
+ {errorMessage}
- {errorMessage && (
-
- {errorMessage}
-
- )}
+ )}
-
- {viewerData?.me ? (
-
- Accept Invite
-
- ) : (
- router.push('/login')}
- >
- Login
-
- )}
-
-
- Don't have an Omnivore account?{' '}
-
-
- Signup
-
-
-
-
-
-
- >
- )
+
+ {viewerData?.me ? (
+
+ Accept Invite
+
+ ) : (
+ router.push('/login')}
+ >
+ Login
+
+ )}
+
+
+ Don't have an Omnivore account?{' '}
+
+
+ Signup
+
+
+
+
+
+
+ >;
}
diff --git a/packages/web/pages/settings/emails/index.tsx b/packages/web/pages/settings/emails/index.tsx
index 4d9bc776a..266a33a6b 100644
--- a/packages/web/pages/settings/emails/index.tsx
+++ b/packages/web/pages/settings/emails/index.tsx
@@ -114,145 +114,143 @@ export default function EmailsPage(): JSX.Element {
return emailAddresses.sort((a, b) => a.createdAt.localeCompare(b.createdAt))
}, [emailAddresses])
- return (
- <>
- {
- createEmail()
+ return <>
+ {
+ createEmail()
+ },
+ }}
+ >
+ {sortedEmailAddresses.length > 0 ? (
+ sortedEmailAddresses.map((email, i) => {
+ return (
+ setConfirmDeleteEmailId(email.id)}
+ deleteTitle="Delete"
+ sublineElement={
+
+ {`created ${formattedShortDate(email.createdAt)}, `}
+ {`${email.subscriptionCount} subscriptions`}
+
+ }
+ titleElement={
+
+
+
+ }
+ extraElement={
+ email.confirmationCode ? (
+
+ <>
+
+ {`Gmail: ${email.confirmationCode}`}
+
+
+
+
+
+
+ >
+
+ ) : (
+ <>>
+ )
+ }
+ />
+ );
+ })
+ ) : (
+
+ )}
+
- {sortedEmailAddresses.length > 0 ? (
- sortedEmailAddresses.map((email, i) => {
- return (
- setConfirmDeleteEmailId(email.id)}
- deleteTitle="Delete"
- sublineElement={
-
- {`created ${formattedShortDate(email.createdAt)}, `}
- {`${email.subscriptionCount} subscriptions`}
-
- }
- titleElement={
-
-
-
- }
- extraElement={
- email.confirmationCode ? (
-
- <>
-
- {`Gmail: ${email.confirmationCode}`}
-
-
-
-
-
-
- >
-
- ) : (
- <>>
- )
- }
- />
- )
- })
- ) : (
-
- )}
-
-
- View recently received emails
-
-
-
+
+ View recently received emails
+
+
+
- {confirmDeleteEmailId ? (
- {
- await deleteEmail(confirmDeleteEmailId)
- setConfirmDeleteEmailId(undefined)
- }}
- onOpenChange={() => setConfirmDeleteEmailId(undefined)}
- />
- ) : null}
- >
- )
+ {confirmDeleteEmailId ? (
+ {
+ await deleteEmail(confirmDeleteEmailId)
+ setConfirmDeleteEmailId(undefined)
+ }}
+ onOpenChange={() => setConfirmDeleteEmailId(undefined)}
+ />
+ ) : null}
+ >;
}
diff --git a/packages/web/pages/settings/subscriptions.tsx b/packages/web/pages/settings/subscriptions.tsx
index 90a9f9cec..95f48a7eb 100644
--- a/packages/web/pages/settings/subscriptions.tsx
+++ b/packages/web/pages/settings/subscriptions.tsx
@@ -86,7 +86,7 @@ export default function SubscriptionsPage(): JSX.Element {
at{' '}
+ legacyBehavior>
{subscription.newsletterEmail}
>
@@ -101,7 +101,7 @@ export default function SubscriptionsPage(): JSX.Element {
}
/>
- )
+ );
})
) : (
- )
+ );
}
diff --git a/packages/web/public/static/landing/landingPage-feature@2x.png b/packages/web/public/static/images/landing/landing-00-hero.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-feature@2x.png
rename to packages/web/public/static/images/landing/landing-00-hero.png
diff --git a/packages/web/public/static/landing/landingPage-03@2x.png b/packages/web/public/static/images/landing/landing-01-save-it-now.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-03@2x.png
rename to packages/web/public/static/images/landing/landing-01-save-it-now.png
diff --git a/packages/web/public/static/landing/landingPage-04@2x.png b/packages/web/public/static/images/landing/landing-02-newsletters.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-04@2x.png
rename to packages/web/public/static/images/landing/landing-02-newsletters.png
diff --git a/packages/web/public/static/landing/landingPage-05@2x.png b/packages/web/public/static/images/landing/landing-03-organisation.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-05@2x.png
rename to packages/web/public/static/images/landing/landing-03-organisation.png
diff --git a/packages/web/public/static/landing/landingPage-06@2x.png b/packages/web/public/static/images/landing/landing-04-highlights-and-notes.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-06@2x.png
rename to packages/web/public/static/images/landing/landing-04-highlights-and-notes.png
diff --git a/packages/web/public/static/landing/landingPage-07@2x.png b/packages/web/public/static/images/landing/landing-05-sync.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-07@2x.png
rename to packages/web/public/static/images/landing/landing-05-sync.png
diff --git a/packages/web/public/static/landing/landingPage-08@2x.png b/packages/web/public/static/images/landing/landing-06-tts.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-08@2x.png
rename to packages/web/public/static/images/landing/landing-06-tts.png
diff --git a/packages/web/public/static/landing/landingPage-09@2x.png b/packages/web/public/static/images/landing/landing-07-oss.png
similarity index 100%
rename from packages/web/public/static/landing/landingPage-09@2x.png
rename to packages/web/public/static/images/landing/landing-07-oss.png
diff --git a/packages/web/public/static/images/login/login-feature-image-full.png b/packages/web/public/static/images/login/login-feature-image-full.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e4ea19620bebff4a21b72074effed5cb2b4c999
GIT binary patch
literal 204315
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