Create build step for the web server (#289)
* Create build step for the web server * Update bskyweb routes and 404 behaviorzio/stable
parent
8629e167cd
commit
8d2e649b4d
2
app.json
2
app.json
|
@ -7,7 +7,7 @@
|
|||
"icon": "./assets/icon.png",
|
||||
"userInterfaceStyle": "light",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"image": "./assets/cloud-splash.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
|
|
|
@ -20,8 +20,7 @@ like:
|
|||
Then build and copy over the big 'ol `bundle.web.js` file:
|
||||
|
||||
# in the top level of this repo
|
||||
yarn webpack build --config ./web/webpack.config.js -d inline-source-map --color
|
||||
cp dist/bundle.web.js bskyweb/static/
|
||||
yarn build-web
|
||||
|
||||
### Golang Daemon
|
||||
|
||||
|
|
|
@ -94,20 +94,23 @@ func serve(cctx *cli.Context) error {
|
|||
// configure routes
|
||||
e.File("/robots.txt", "static/robots.txt")
|
||||
e.Static("/static", "static")
|
||||
e.Static("/static/js", "../web-build/static/js")
|
||||
|
||||
e.GET("/", server.WebHome)
|
||||
|
||||
// generic routes
|
||||
e.GET("/contacts", server.WebGeneric)
|
||||
e.GET("/search", server.WebGeneric)
|
||||
e.GET("/notifications", server.WebGeneric)
|
||||
e.GET("/settings", server.WebGeneric)
|
||||
e.GET("/settings", server.WebGeneric)
|
||||
e.GET("/sys/debug", server.WebGeneric)
|
||||
e.GET("/sys/log", server.WebGeneric)
|
||||
e.GET("/support", server.WebGeneric)
|
||||
e.GET("/support/privacy", server.WebGeneric)
|
||||
|
||||
// profile endpoints; only first populates info
|
||||
e.GET("/profile/:handle", server.WebProfile)
|
||||
e.GET("/profile/:handle/follows", server.WebGeneric)
|
||||
e.GET("/profile/:handle/following", server.WebGeneric)
|
||||
e.GET("/profile/:handle/followers", server.WebGeneric)
|
||||
|
||||
// post endpoints; only first populates info
|
||||
e.GET("/profile/:handle/post/:rkey", server.WebPost)
|
||||
|
|
|
@ -2,21 +2,120 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover">
|
||||
<meta name="referrer" content="origin-when-cross-origin">
|
||||
<title>{%- block head_title -%}Bluesky{%- endblock -%}</title>
|
||||
|
||||
<!-- Hello Humans! API docs at https://atproto.com -->
|
||||
|
||||
<style>
|
||||
/* These styles make the body full-height */
|
||||
html, body { height: 100%; }
|
||||
/* These styles disable body scrolling if you are using <ScrollView> */
|
||||
body { overflow: hidden; }
|
||||
/* These styles make the root element full-height */
|
||||
#app-root { display:flex; height:100%; }
|
||||
/**
|
||||
* Extend the react-native-web reset:
|
||||
* https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js
|
||||
*/
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
width: 100%;
|
||||
/* To smooth any scrolling behavior */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
/* Allows content to fill the viewport and go beyond the bottom */
|
||||
min-height: 100%;
|
||||
}
|
||||
#root {
|
||||
flex-shrink: 0;
|
||||
flex-basis: auto;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
/* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
height: calc(100% + env(safe-area-inset-top));
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
/* Allows you to scroll below the viewport; default value is visible */
|
||||
overflow-y: auto;
|
||||
overscroll-behavior-y: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
/* Enable for apps that support dark-theme */
|
||||
/*@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* Remove focus state on inputs */
|
||||
*:focus { outline: 0; }
|
||||
*:focus {
|
||||
outline: 0;
|
||||
}
|
||||
/* Remove default link styling */
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
a[role="link"]:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ProseMirror */
|
||||
.ProseMirror {
|
||||
font: 18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
min-height: 140px;
|
||||
}
|
||||
.ProseMirror p {
|
||||
margin: 0;
|
||||
}
|
||||
.ProseMirror p.is-editor-empty:first-child::before {
|
||||
color: #8d8e96;
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ProseMirror .mention {
|
||||
color: #0085ff;
|
||||
}
|
||||
.ProseMirror a {
|
||||
color: #0085ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tippy-content .items {
|
||||
border-radius: 6px;
|
||||
background: #F3F3F8;
|
||||
border: 1px solid #e0d9d9;
|
||||
padding: 3px 3px;
|
||||
}
|
||||
.tippy-content .items .item {
|
||||
display: block;
|
||||
background: transparent;
|
||||
color: #8a8c9a;
|
||||
border: 0;
|
||||
font: 17px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
padding: 7px 10px 8px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
.tippy-content .items .item.is-selected {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
{% block head_bundle -%}<script defer src="/static/bundle.web.js"></script>{%- endblock %}
|
||||
{% include "scripts.html" %}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png"/>
|
||||
|
@ -38,14 +137,13 @@
|
|||
</head>
|
||||
<body>
|
||||
{%- block body_all %}
|
||||
<div id="app-root">
|
||||
<div id="root"></div>
|
||||
<noscript>
|
||||
{%- block noscript_extra %}{% endblock -%}
|
||||
<h1>Javascript Required</h1>
|
||||
<p>This is a heavily interactive web application, and Javascript is required. Simple HTML interfaces are possible, but that is not what this is.
|
||||
<p>Learn more about Bluesky at <a href="https://blueskyweb.xyz">blueskyweb.xyz</a> and <a href="https://atproto.com">atproto.com</a>.
|
||||
</noscript>
|
||||
</div>
|
||||
{% endblock -%}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,14 +2,26 @@
|
|||
|
||||
{% block head_title %}Error {{ statusCode }} - Bluesky{% endblock %}
|
||||
|
||||
{# don't include the bundle on error pages #}
|
||||
{% block head_bundle %}{% endblock %}
|
||||
|
||||
{% block body_all %}
|
||||
{% if statusCode == 404 %}
|
||||
<h1>404: Not Found</h1>
|
||||
{% else %}
|
||||
<h1>{{ statusCode }}: Server Error</h1>
|
||||
<p>Sorry about that! Our <a href="https://bluesky.statuspage.io/">Status Page</a> might have more context.
|
||||
{% block noscript_extra %}
|
||||
{%- if statusCode == 404 %}
|
||||
<h1>404: Not Found</h1>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{# don't include the bundle on non-404 error pages #}
|
||||
{% block head_bundle %}
|
||||
{% if statusCode == 404 %}
|
||||
{{ super() }}
|
||||
{% else %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{%- block body_all %}
|
||||
{% if statusCode == 404 %}
|
||||
{{ super() }}
|
||||
{% else %}
|
||||
<h1>{{ statusCode }}: Server Error</h1>
|
||||
<p>Sorry about that! Our <a href="https://bluesky.statuspage.io/">Status Page</a> might have more context.
|
||||
{% endif %}
|
||||
{% endblock -%}
|
|
@ -0,0 +1,2 @@
|
|||
<script defer="defer" src="/static/js/412.e47ad7b9.js"></script>
|
||||
<script defer="defer" src="/static/js/main.f526ceaa.js"></script>
|
|
@ -6,6 +6,7 @@
|
|||
"android": "expo run:android",
|
||||
"ios": "expo run:ios",
|
||||
"web": "expo start --web",
|
||||
"build-web": "expo export:web && node ./scripts/post-web-build.js",
|
||||
"start": "expo start --dev-client",
|
||||
"clean-cache": "rm -rf node_modules/.cache/babel-loader/*",
|
||||
"test": "jest --forceExit --testTimeout=20000 --bail",
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
const projectRoot = path.join(__dirname, '..')
|
||||
const webBuildJs = path.join(projectRoot, 'web-build', 'static', 'js')
|
||||
const templateFile = path.join(
|
||||
projectRoot,
|
||||
'bskyweb',
|
||||
'templates',
|
||||
'scripts.html',
|
||||
)
|
||||
|
||||
const jsFiles = fs.readdirSync(webBuildJs).filter(name => name.endsWith('.js'))
|
||||
jsFiles.sort((a, b) => {
|
||||
// make sure main is written last
|
||||
if (a.startsWith('main')) return 1
|
||||
if (b.startsWith('main')) return -1
|
||||
return a.localeCompare(b)
|
||||
})
|
||||
|
||||
console.log(`Found ${jsFiles.length} js files in web-build`)
|
||||
console.log(`Writing ${templateFile}`)
|
||||
|
||||
const outputFile = jsFiles
|
||||
.map(name => `<script defer="defer" src="/static/js/${name}"></script>`)
|
||||
.join('\n')
|
||||
fs.writeFileSync(templateFile, outputFile)
|
|
@ -238,7 +238,7 @@ const styles = StyleSheet.create({
|
|||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 136,
|
||||
width: 138,
|
||||
borderRadius: 24,
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 16,
|
||||
|
|
Loading…
Reference in New Issue