Create build step for the web server (#289)
* Create build step for the web server * Update bskyweb routes and 404 behavior
This commit is contained in:
		
							parent
							
								
									8629e167cd
								
							
						
					
					
						commit
						8d2e649b4d
					
				
					 9 changed files with 169 additions and 27 deletions
				
			
		
							
								
								
									
										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 -%}
 | 
			
		||||
							
								
								
									
										2
									
								
								bskyweb/templates/scripts.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								bskyweb/templates/scripts.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								scripts/post-web-build.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								scripts/post-web-build.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue