Merge pull request #261 from omnivore-app/experiment/appreader

Bundled appreader for iOS
This commit is contained in:
Jackson Harper
2022-03-21 17:29:05 -07:00
committed by GitHub
10 changed files with 282 additions and 1 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}

View File

@ -0,0 +1,3 @@
**/node_modules/*
**/out/*
**/.next/*

View File

@ -0,0 +1,26 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json"
},
"plugins": ["@typescript-eslint", "functional"],
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"prettier",
"plugin:functional/no-object-orientation"
],
"root": true,
"env": {
"es6": true,
"browser": true,
"jest": true,
"node": true
},
"ignorePatterns": ["next.config.js", "jest.config.js"],
"rules": {
"functional/no-mixed-type": 0,
"react/react-in-jsx-scope": 0
}
}

9
packages/appreader/additional.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
export {}
declare global {
interface Window {
omnivoreArticle?: any
omnivoreEnv?: any
fontSize?: number
}
}

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no' />
</head>
<body>
<div id="root">
<!-- {{INJECT_SWIFT_STRING_HERE!!}} -->
<script type="text/javascript">
function loadEnv() {
window.omnivoreEnv = {
"NEXT_PUBLIC_APP_ENV":"local",
"NEXT_PUBLIC_LOCAL_BASE_URL":"http://localhost:3000",
"NEXT_PUBLIC_LOCAL_SERVER_BASE_URL":"http://localhost:4000",
"NEXT_PUBLIC_LOCAL_HIGHLIGHTS_BASE_URL":"http://localhost:4000"
}
}
function loadArticle() {
const CONTENT = `
<div class="page" id="readability-page-1" data-omnivore-anchor-idx="1"><div data-omnivore-anchor-idx="2">
<p data-omnivore-anchor-idx="3">I didn't have time to write a short email so I scheduled a long meeting.</p><p data-omnivore-anchor-idx="4">
— <a href="https://twitter.com/jacksonh" data-omnivore-anchor-idx="5">jacksonh</a> Jackson Harper <a href="https://twitter.com/jacksonh/status/1069798258141159425" data-omnivore-anchor-idx="6">December 4, 2018, 3:39 AM UTC</a>
</p></div></div>
`;
window.omnivoreArticle = {
id: "test",
linkId: "test",
slug: "test-slug",
createdAt: new Date().toISOString(),
savedAt: new Date().toISOString(),
url: "https://example.com",
title: "Test Article",
content: CONTENT,
originalArticleUrl: "https://example.com",
contentReader: "WEB",
readingProgressPercent: 0,
readingProgressAnchorIndex: 0,
highlights: [],
}
}
loadEnv()
loadArticle()
</script>
</div>
<script src="bundle.js"></script>
</body>
</html>

View File

@ -0,0 +1,37 @@
{
"name": "@omnivore/appreader",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "webpack --mode production"
},
"dependencies": {
"@omnivore/web": "1.0.0"
},
"devDependencies": {
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"@babel/core": "^7.17.7",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@babel/runtime": "^7.17.7",
"@types/string-replace-loader": "^2.3.2",
"@types/webpack-bundle-analyzer": "^4.4.1",
"@types/webpack-dev-server": "^4.7.2",
"babel-loader": "^8.2.3",
"css-loader": "^6.7.1",
"eslint-config-next": "12.0.7",
"eslint-plugin-functional": "^4.0.2",
"eslint-plugin-react": "^7.28.0",
"string-replace-loader": "^3.1.0",
"style-loader": "^3.3.1",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-dev-server": "^4.7.4"
},
"volta": {
"node": "14.18.0",
"yarn": "1.22.10"
}
}

View File

@ -0,0 +1,43 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Box, VStack } from '@omnivore/web/components/elements/LayoutPrimitives'
import { ArticleContainer } from '@omnivore/web/components/templates/article/ArticleContainer'
import { ArticleAttributes } from '@omnivore/web/lib/networking/queries/useGetArticleQuery'
import { applyStoredTheme } from '@omnivore/web/lib/themeUpdater'
import '@omnivore/web/styles/globals.css'
import '@omnivore/web/styles/articleInnerStyling.css'
const App = () => {
applyStoredTheme(false) // false to skip serevr sync
return (
<>
<Box
css={{
overflowY: 'auto',
height: '100%',
width: '100vw',
}}
>
<VStack
alignment="center"
distribution="center"
className="disable-webkit-callout"
>
<ArticleContainer
viewerUsername="test"
article={window.omnivoreArticle as ArticleAttributes}
scrollElementRef={React.createRef()}
isAppleAppEmbed={true}
highlightBarDisabled={true}
highlightsBaseURL="https://example.com"
fontSize={window.fontSize ?? 18}
margin={0}
/>
</VStack>
</Box>
</>
)
}
ReactDOM.render(<App />, document.getElementById('root'))

View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["additional.d.ts", "src"]
}

View File

@ -0,0 +1,79 @@
import path from "path"
import glob from 'glob'
import { DefinePlugin } from 'webpack'
import { Configuration } from "webpack"
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
const analyze = process.env.ANALYZE
const config: Configuration = {
entry: {
bundle: './src/index.tsx',
fonts: [
...glob.sync('../web/public/static/fonts/Inter/*'),
...glob.sync('../web/public/static/fonts/SFMono/*')
],
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
["@babel/preset-react", {"runtime": "automatic"}],
"@babel/preset-typescript",
],
},
},
},
{
test: /\.css$/i,
use: ['style-loader', {
loader: 'css-loader',
options: { url: false }
}, {
// We want paths like `/static/fonts/Inter/Inter.woff2 to become
// `Inter.woff2` which is how they will be bundled on iOS.
loader: 'string-replace-loader',
options: {
search: '\(\'/static/fonts/.*/(.*)\'\)',
replace(_s: string, _p: string, group: string) {
return group
},
flags: 'g',
},
}],
},
{
test: /.(ttf|otf|woff(2)?)(\?[a-z0-9]+)?$/,
type: 'asset/resource',
generator: {
filename: '[path][name][ext]'
}
},
],
},
plugins: [
new DefinePlugin({
'process.env': 'window.omnivoreEnv',
}),
new BundleAnalyzerPlugin({
openAnalyzer: !!analyze,
analyzerMode: 'static',
})
],
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
path: path.resolve(__dirname, "build"),
filename: '[name].js',
},
};
export default config;