fix: update Sapper to latest (#775)
* fix: update to latest sapper fixes #416 * fix error and debug pages * requestIdleCallback makes column switching feel way nicer than double rAF * add export feature * add better csp info * workaround for sapper sub-page issue * clarify in readme about exporting * fix now config * switch from rIC to triple raf * style-loader is no longer used * update theming guide
							
								
								
									
										9
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						| 
						 | 
					@ -1,11 +1,14 @@
 | 
				
			||||||
.DS_Store
 | 
					.DS_Store
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
.sapper
 | 
					.sapper
 | 
				
			||||||
 | 
					__sapper__
 | 
				
			||||||
yarn.lock
 | 
					yarn.lock
 | 
				
			||||||
templates/.*
 | 
					templates/.*
 | 
				
			||||||
assets/*.css
 | 
					static/*.css
 | 
				
			||||||
/mastodon
 | 
					/mastodon
 | 
				
			||||||
mastodon.log
 | 
					mastodon.log
 | 
				
			||||||
assets/robots.txt
 | 
					static/robots.txt
 | 
				
			||||||
/inline-script-checksum.json
 | 
					/inline-script-checksum.json
 | 
				
			||||||
/assets/inline-script.js.map
 | 
					/static/inline-script.js.map
 | 
				
			||||||
 | 
					/templates/.*
 | 
				
			||||||
 | 
					/src/manifest/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								README.md
									
										
									
									
									
								
							
							
						
						| 
						 | 
					@ -76,6 +76,16 @@ To keep your version of Pinafore up to date, you can use `git` to check out the
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    git checkout $(git tag -l | sort -Vr | head -n 1)
 | 
					    git checkout $(git tag -l | sort -Vr | head -n 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Exporting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can export Pinafore as a static site. Run:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    npm run export
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Static files will be written to `__sapper__/export`.
 | 
				
			||||||
 | 
					Be sure to add the [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) header printed out in the console to
 | 
				
			||||||
 | 
					your server config!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Developing and testing
 | 
					## Developing and testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
See [CONTRIBUTING.md](https://github.com/nolanlawson/pinafore/blob/master/CONTRIBUTING.md) for 
 | 
					See [CONTRIBUTING.md](https://github.com/nolanlawson/pinafore/blob/master/CONTRIBUTING.md) for 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ import { rollup } from 'rollup'
 | 
				
			||||||
import { terser } from 'rollup-plugin-terser'
 | 
					import { terser } from 'rollup-plugin-terser'
 | 
				
			||||||
import replace from 'rollup-plugin-replace'
 | 
					import replace from 'rollup-plugin-replace'
 | 
				
			||||||
import fromPairs from 'lodash-es/fromPairs'
 | 
					import fromPairs from 'lodash-es/fromPairs'
 | 
				
			||||||
import { themes } from '../routes/_static/themes'
 | 
					import { themes } from '../src/routes/_static/themes'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const readFile = pify(fs.readFile.bind(fs))
 | 
					const readFile = pify(fs.readFile.bind(fs))
 | 
				
			||||||
const writeFile = pify(fs.writeFile.bind(fs))
 | 
					const writeFile = pify(fs.writeFile.bind(fs))
 | 
				
			||||||
| 
						 | 
					@ -36,22 +36,22 @@ async function main () {
 | 
				
			||||||
    sourcemap: true
 | 
					    sourcemap: true
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let fullCode = `${code}\n//# sourceMappingURL=inline-script.js.map`
 | 
					  let fullCode = `${code}\n//# sourceMappingURL=/inline-script.js.map`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let checksum = crypto.createHash('sha256').update(fullCode).digest('base64')
 | 
					  let checksum = crypto.createHash('sha256').update(fullCode).digest('base64')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let checksumFilepath = path.join(__dirname, '../inline-script-checksum.json')
 | 
					  let checksumFilepath = path.join(__dirname, '../inline-script-checksum.json')
 | 
				
			||||||
  await writeFile(checksumFilepath, JSON.stringify({ checksum }), 'utf8')
 | 
					  await writeFile(checksumFilepath, JSON.stringify({ checksum }), 'utf8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let html2xxFilepath = path.join(__dirname, '../templates/2xx.html')
 | 
					  let htmlTemplateFilepath = path.join(__dirname, '../src/template.html')
 | 
				
			||||||
  let html2xxFile = await readFile(html2xxFilepath, 'utf8')
 | 
					  let htmlTemplateFile = await readFile(htmlTemplateFilepath, 'utf8')
 | 
				
			||||||
  html2xxFile = html2xxFile.replace(
 | 
					  htmlTemplateFile = htmlTemplateFile.replace(
 | 
				
			||||||
    /<!-- insert inline script here -->[\s\S]+<!-- end insert inline script here -->/,
 | 
					    /<!-- insert inline script here -->[\s\S]+<!-- end insert inline script here -->/,
 | 
				
			||||||
    '<!-- insert inline script here --><script>' + fullCode + '</script><!-- end insert inline script here -->'
 | 
					    '<!-- insert inline script here --><script>' + fullCode + '</script><!-- end insert inline script here -->'
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  await writeFile(html2xxFilepath, html2xxFile, 'utf8')
 | 
					  await writeFile(htmlTemplateFilepath, htmlTemplateFile, 'utf8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await writeFile(path.resolve(__dirname, '../assets/inline-script.js.map'), map.toString(), 'utf8')
 | 
					  await writeFile(path.resolve(__dirname, '../static/inline-script.js.map'), map.toString(), 'utf8')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main().catch(err => {
 | 
					main().catch(err => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,10 @@ const globalScss = path.join(__dirname, '../scss/global.scss')
 | 
				
			||||||
const defaultThemeScss = path.join(__dirname, '../scss/themes/_default.scss')
 | 
					const defaultThemeScss = path.join(__dirname, '../scss/themes/_default.scss')
 | 
				
			||||||
const offlineThemeScss = path.join(__dirname, '../scss/themes/_offline.scss')
 | 
					const offlineThemeScss = path.join(__dirname, '../scss/themes/_offline.scss')
 | 
				
			||||||
const customScrollbarScss = path.join(__dirname, '../scss/custom-scrollbars.scss')
 | 
					const customScrollbarScss = path.join(__dirname, '../scss/custom-scrollbars.scss')
 | 
				
			||||||
const html2xxFile = path.join(__dirname, '../templates/2xx.html')
 | 
					const htmlTemplateFile = path.join(__dirname, '../src/template.html')
 | 
				
			||||||
const scssDir = path.join(__dirname, '../scss')
 | 
					const scssDir = path.join(__dirname, '../scss')
 | 
				
			||||||
const themesScssDir = path.join(__dirname, '../scss/themes')
 | 
					const themesScssDir = path.join(__dirname, '../scss/themes')
 | 
				
			||||||
const assetsDir = path.join(__dirname, '../assets')
 | 
					const assetsDir = path.join(__dirname, '../static')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function doWatch () {
 | 
					function doWatch () {
 | 
				
			||||||
  let start = now()
 | 
					  let start = now()
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ async function compileGlobalSass () {
 | 
				
			||||||
  let offlineStyle = (await renderCss(offlineThemeScss))
 | 
					  let offlineStyle = (await renderCss(offlineThemeScss))
 | 
				
			||||||
  let scrollbarStyle = (await renderCss(customScrollbarScss))
 | 
					  let scrollbarStyle = (await renderCss(customScrollbarScss))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let html = await readFile(html2xxFile, 'utf8')
 | 
					  let html = await readFile(htmlTemplateFile, 'utf8')
 | 
				
			||||||
  html = html.replace(/<!-- begin inline CSS -->[\s\S]+<!-- end inline CSS -->/,
 | 
					  html = html.replace(/<!-- begin inline CSS -->[\s\S]+<!-- end inline CSS -->/,
 | 
				
			||||||
    `<!-- begin inline CSS -->\n` +
 | 
					    `<!-- begin inline CSS -->\n` +
 | 
				
			||||||
    `<style>\n${mainStyle}</style>\n` +
 | 
					    `<style>\n${mainStyle}</style>\n` +
 | 
				
			||||||
| 
						 | 
					@ -53,7 +53,7 @@ async function compileGlobalSass () {
 | 
				
			||||||
    `<!-- end inline CSS -->`
 | 
					    `<!-- end inline CSS -->`
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await writeFile(html2xxFile, html, 'utf8')
 | 
					  await writeFile(htmlTemplateFile, html, 'utf8')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function compileThemesSass () {
 | 
					async function compileThemesSass () {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,13 +28,13 @@ async function main () {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  result = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">\n${result}\n</svg>`
 | 
					  result = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">\n${result}\n</svg>`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let html2xxFilepath = path.join(__dirname, '../templates/2xx.html')
 | 
					  let htmlTemplateFilepath = path.join(__dirname, '../src/template.html')
 | 
				
			||||||
  let html2xxFile = await readFile(html2xxFilepath, 'utf8')
 | 
					  let htmlTemplateFile = await readFile(htmlTemplateFilepath, 'utf8')
 | 
				
			||||||
  html2xxFile = html2xxFile.replace(
 | 
					  htmlTemplateFile = htmlTemplateFile.replace(
 | 
				
			||||||
    /<!-- insert svg here -->[\s\S]+<!-- end insert svg here -->/,
 | 
					    /<!-- insert svg here -->[\s\S]+<!-- end insert svg here -->/,
 | 
				
			||||||
    '<!-- insert svg here -->' + result + '<!-- end insert svg here -->'
 | 
					    '<!-- insert svg here -->' + result + '<!-- end insert svg here -->'
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  await writeFile(html2xxFilepath, html2xxFile, 'utf8')
 | 
					  await writeFile(htmlTemplateFilepath, htmlTemplateFile, 'utf8')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main().catch(err => {
 | 
					main().catch(err => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,9 +7,9 @@ PATH="$PATH:./node_modules/.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# set up robots.txt
 | 
					# set up robots.txt
 | 
				
			||||||
if [[ "$DEPLOY_TYPE" == "dev" ]]; then
 | 
					if [[ "$DEPLOY_TYPE" == "dev" ]]; then
 | 
				
			||||||
  printf 'User-agent: *\nDisallow: /' > assets/robots.txt
 | 
					  printf 'User-agent: *\nDisallow: /' > static/robots.txt
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
  rm -f assets/robots.txt
 | 
					  rm -f static/robots.txt
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# if in travis, use the $NOW_TOKEN
 | 
					# if in travis, use the $NOW_TOKEN
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										48
									
								
								bin/print-export-info.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					const fs = require('fs')
 | 
				
			||||||
 | 
					const path = require('path')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const checksum = require('../inline-script-checksum').checksum
 | 
				
			||||||
 | 
					const html = fs.readFileSync(path.join(__dirname, '../__sapper__/export/index.html'), 'utf8')
 | 
				
			||||||
 | 
					const nonce = html.match(/<script nonce=([^>]+)>/)[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const csp = `add_header Content-Security-Policy "script-src 'self' 'sha256-${checksum}' 'nonce-${nonce}'; ` +
 | 
				
			||||||
 | 
					`worker-src 'self'; style-src 'self' 'unsafe-inline'; frame-src 'none'; object-src 'none'; manifest-src 'self';`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fs.writeFileSync(path.join(__dirname, '../__sapper__/export/.csp.nginx'), csp, 'utf8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log(`                                                                                             
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					               ,((*
 | 
				
			||||||
 | 
					               ,((*   (,
 | 
				
			||||||
 | 
					               ,((*   (((*
 | 
				
			||||||
 | 
					               ,((*   (((((.
 | 
				
			||||||
 | 
					            *  ,((*   ((((((*
 | 
				
			||||||
 | 
					          .(/  ,((*   (((((((/
 | 
				
			||||||
 | 
					         .((/  ,((*   ((((((((/
 | 
				
			||||||
 | 
					        ,(((/  ,((*   (((((((((*
 | 
				
			||||||
 | 
					      .(((((/  ,((*   ((((((((((
 | 
				
			||||||
 | 
					               ,((*
 | 
				
			||||||
 | 
					     //////////((((/////////////
 | 
				
			||||||
 | 
					     /((((((((((((((((((((((((((
 | 
				
			||||||
 | 
					      /((((((((((((((((((((((((,
 | 
				
			||||||
 | 
					       *(((((((((((((((((((((/.
 | 
				
			||||||
 | 
					         ./((((((((((((((((.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           P I N A F O R E
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Export successful! Static files are in:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __sapper__/export/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Be sure to add the CSP header to your nginx config:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    server {
 | 
				
			||||||
 | 
					        include ${path.resolve(__dirname, '..')}/__sapper__/export/.csp.nginx;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This file will be updated whenever you do \`npm run export\`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Enjoy Pinafore!
 | 
				
			||||||
 | 
					`)
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
import { actions } from './mastodon-data'
 | 
					import { actions } from './mastodon-data'
 | 
				
			||||||
import { users } from '../tests/users'
 | 
					import { users } from '../tests/users'
 | 
				
			||||||
import { postStatus } from '../routes/_api/statuses'
 | 
					import { postStatus } from '../src/routes/_api/statuses'
 | 
				
			||||||
import { followAccount } from '../routes/_api/follow'
 | 
					import { followAccount } from '../src/routes/_api/follow'
 | 
				
			||||||
import { favoriteStatus } from '../routes/_api/favorite'
 | 
					import { favoriteStatus } from '../src/routes/_api/favorite'
 | 
				
			||||||
import { reblogStatus } from '../routes/_api/reblog'
 | 
					import { reblogStatus } from '../src/routes/_api/reblog'
 | 
				
			||||||
import fetch from 'node-fetch'
 | 
					import fetch from 'node-fetch'
 | 
				
			||||||
import FileApi from 'file-api'
 | 
					import FileApi from 'file-api'
 | 
				
			||||||
import { pinStatus } from '../routes/_api/pin'
 | 
					import { pinStatus } from '../src/routes/_api/pin'
 | 
				
			||||||
import { submitMedia } from '../tests/submitMedia'
 | 
					import { submitMedia } from '../tests/submitMedia'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global.File = FileApi.File
 | 
					global.File = FileApi.File
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
module.exports = [
 | 
					module.exports = [
 | 
				
			||||||
  { id: 'pinafore-logo', src: 'original-assets/sailboat.svg', title: 'Home' },
 | 
					  { id: 'pinafore-logo', src: 'original-static/sailboat.svg', title: 'Home' },
 | 
				
			||||||
  { id: 'fa-bell', src: 'node_modules/font-awesome-svg-png/white/svg/bell.svg', title: 'Notifications' },
 | 
					  { id: 'fa-bell', src: 'node_modules/font-awesome-svg-png/white/svg/bell.svg', title: 'Notifications' },
 | 
				
			||||||
  { id: 'fa-users', src: 'node_modules/font-awesome-svg-png/white/svg/users.svg', title: 'Local' },
 | 
					  { id: 'fa-users', src: 'node_modules/font-awesome-svg-png/white/svg/users.svg', title: 'Local' },
 | 
				
			||||||
  { id: 'fa-globe', src: 'node_modules/font-awesome-svg-png/white/svg/globe.svg', title: 'Federated' },
 | 
					  { id: 'fa-globe', src: 'node_modules/font-awesome-svg-png/white/svg/globe.svg', title: 'Federated' },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
## Theming
 | 
					## Theming
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create a file `scss/themes/foobar.scss`, write some SCSS inside and add the following at the bottom of `scss/themes/foobar.scss`.
 | 
					This document describes how to write your own theme for Pinafore.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First, create a file `scss/themes/foobar.scss`, write some SCSS inside and add
 | 
				
			||||||
 | 
					the following at the bottom of `scss/themes/foobar.scss`.
 | 
				
			||||||
```scss
 | 
					```scss
 | 
				
			||||||
@import "_base.scss";
 | 
					@import "_base.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +12,10 @@ body.theme-foobar {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> Note: You can find all the SCSS variables available in `scss/themes/_default.scss` while the all CSS Custom Properties available are listed in `scss/themes/_base.scss`.
 | 
					> Note: You can find all the SCSS variables available in `scss/themes/_default.scss` 
 | 
				
			||||||
 | 
					> while the all CSS Custom Properties available are listed in `scss/themes/_base.scss`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Add your theme to `routes/_static/themes.js`
 | 
					Then, Add your theme to `src/routes/_static/themes.js`
 | 
				
			||||||
```js
 | 
					```js
 | 
				
			||||||
const themes = [
 | 
					const themes = [
 | 
				
			||||||
  ...
 | 
					  ...
 | 
				
			||||||
| 
						 | 
					@ -24,4 +28,7 @@ const themes = [
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Start the development server (`npm run dev`), go to `http://localhost:4002/settings/instances/your-instance-name` and select your newly created theme. Once you've done that, you can update your theme, and refresh the page to see the change (you don't have to restart the server).
 | 
					Start the development server (`npm run dev`), go to 
 | 
				
			||||||
 | 
					`http://localhost:4002/settings/instances/your-instance-name` and select your 
 | 
				
			||||||
 | 
					newly-created theme. Once you've done that, you can update your theme, and refresh 
 | 
				
			||||||
 | 
					the page to see the change (you don't have to restart the server).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,8 @@
 | 
				
			||||||
// To allow CSP to work correctly, we also calculate a sha256 hash during
 | 
					// To allow CSP to work correctly, we also calculate a sha256 hash during
 | 
				
			||||||
// the build process and write it to inline-script-checksum.json.
 | 
					// the build process and write it to inline-script-checksum.json.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { testHasLocalStorageOnce } from './routes/_utils/testStorage'
 | 
					import { testHasLocalStorageOnce } from './src/routes/_utils/testStorage'
 | 
				
			||||||
import { switchToTheme } from './routes/_utils/themeEngine'
 | 
					import { switchToTheme } from './src/routes/_utils/themeEngine'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
window.__themeColors = process.env.THEME_COLORS
 | 
					window.__themeColors = process.env.THEME_COLORS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 708 B  | 
| 
		 Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB  | 
| 
		 Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 403 B  | 
| 
		 Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B  | 
							
								
								
									
										929
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										41
									
								
								package.json
									
										
									
									
									
								
							
							
						
						| 
						 | 
					@ -3,15 +3,16 @@
 | 
				
			||||||
  "description": "Alternative web client for Mastodon",
 | 
					  "description": "Alternative web client for Mastodon",
 | 
				
			||||||
  "version": "0.13.0",
 | 
					  "version": "0.13.0",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "lint": "standard && standard --plugin html 'routes/**/*.html'",
 | 
					    "lint": "standard && standard --plugin html 'src/routes/**/*.html'",
 | 
				
			||||||
    "lint-fix": "standard --fix && standard --fix --plugin html 'routes/**/*.html'",
 | 
					    "lint-fix": "standard --fix && standard --fix --plugin html 'src/routes/**/*.html'",
 | 
				
			||||||
    "dev": "run-s build-svg build-inline-script serve-dev",
 | 
					    "dev": "run-s build-svg build-inline-script serve-dev",
 | 
				
			||||||
    "serve-dev": "run-p --race build-sass-watch serve",
 | 
					    "serve-dev": "run-p --race build-sass-watch sapper-dev",
 | 
				
			||||||
    "serve": "node server.js",
 | 
					    "sapper-dev": "cross-env PORT=4002 sapper dev",
 | 
				
			||||||
 | 
					    "sapper-prod": "cross-env PORT=4002 node __sapper__/build",
 | 
				
			||||||
    "build": "cross-env NODE_ENV=production npm run build-steps",
 | 
					    "build": "cross-env NODE_ENV=production npm run build-steps",
 | 
				
			||||||
    "build-steps": "run-s globalize-css build-sass build-svg build-inline-script sapper-build deglobalize-css",
 | 
					    "build-steps": "run-s globalize-css build-sass build-svg build-inline-script sapper-build deglobalize-css",
 | 
				
			||||||
    "sapper-build": "sapper build",
 | 
					    "sapper-build": "sapper build",
 | 
				
			||||||
    "start": "cross-env NODE_ENV=production npm run serve",
 | 
					    "start": "cross-env NODE_ENV=production npm run sapper-prod",
 | 
				
			||||||
    "build-and-start": "run-s build start",
 | 
					    "build-and-start": "run-s build start",
 | 
				
			||||||
    "build-svg": "node ./bin/build-svg.js",
 | 
					    "build-svg": "node ./bin/build-svg.js",
 | 
				
			||||||
    "build-inline-script": "node -r esm ./bin/build-inline-script.js",
 | 
					    "build-inline-script": "node -r esm ./bin/build-inline-script.js",
 | 
				
			||||||
| 
						 | 
					@ -36,7 +37,10 @@
 | 
				
			||||||
    "deploy-prod": "DEPLOY_TYPE=prod ./bin/deploy.sh",
 | 
					    "deploy-prod": "DEPLOY_TYPE=prod ./bin/deploy.sh",
 | 
				
			||||||
    "deploy-dev": "DEPLOY_TYPE=dev ./bin/deploy.sh",
 | 
					    "deploy-dev": "DEPLOY_TYPE=dev ./bin/deploy.sh",
 | 
				
			||||||
    "deploy-all-travis": "./bin/deploy-all-travis.sh",
 | 
					    "deploy-all-travis": "./bin/deploy-all-travis.sh",
 | 
				
			||||||
    "backup-mastodon-data": "./bin/backup-mastodon-data.sh"
 | 
					    "backup-mastodon-data": "./bin/backup-mastodon-data.sh",
 | 
				
			||||||
 | 
					    "sapper-export": "sapper export",
 | 
				
			||||||
 | 
					    "print-export-info": "node ./bin/print-export-info.js",
 | 
				
			||||||
 | 
					    "export": "run-s build sapper-export print-export-info"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@gamestdio/websocket": "^0.2.8",
 | 
					    "@gamestdio/websocket": "^0.2.8",
 | 
				
			||||||
| 
						 | 
					@ -48,6 +52,7 @@
 | 
				
			||||||
    "cross-env": "^5.2.0",
 | 
					    "cross-env": "^5.2.0",
 | 
				
			||||||
    "css-loader": "^2.0.0",
 | 
					    "css-loader": "^2.0.0",
 | 
				
			||||||
    "emoji-regex": "^7.0.1",
 | 
					    "emoji-regex": "^7.0.1",
 | 
				
			||||||
 | 
					    "encoding": "^0.1.12",
 | 
				
			||||||
    "escape-html": "^1.0.3",
 | 
					    "escape-html": "^1.0.3",
 | 
				
			||||||
    "esm": "^3.0.84",
 | 
					    "esm": "^3.0.84",
 | 
				
			||||||
    "events-light": "^1.0.5",
 | 
					    "events-light": "^1.0.5",
 | 
				
			||||||
| 
						 | 
					@ -63,12 +68,10 @@
 | 
				
			||||||
    "localstorage-memory": "^1.0.3",
 | 
					    "localstorage-memory": "^1.0.3",
 | 
				
			||||||
    "lodash-es": "^4.17.11",
 | 
					    "lodash-es": "^4.17.11",
 | 
				
			||||||
    "lodash-webpack-plugin": "^0.11.5",
 | 
					    "lodash-webpack-plugin": "^0.11.5",
 | 
				
			||||||
    "mini-css-extract-plugin": "^0.5.0",
 | 
					 | 
				
			||||||
    "mkdirp": "^0.5.1",
 | 
					    "mkdirp": "^0.5.1",
 | 
				
			||||||
    "node-fetch": "^2.3.0",
 | 
					    "node-fetch": "^2.3.0",
 | 
				
			||||||
    "node-sass": "^4.10.0",
 | 
					    "node-sass": "^4.10.0",
 | 
				
			||||||
    "npm-run-all": "^4.1.5",
 | 
					    "npm-run-all": "^4.1.5",
 | 
				
			||||||
    "optimize-css-assets-webpack-plugin": "^5.0.1",
 | 
					 | 
				
			||||||
    "p-any": "^1.1.0",
 | 
					    "p-any": "^1.1.0",
 | 
				
			||||||
    "page-lifecycle": "^0.1.1",
 | 
					    "page-lifecycle": "^0.1.1",
 | 
				
			||||||
    "performance-now": "^2.1.0",
 | 
					    "performance-now": "^2.1.0",
 | 
				
			||||||
| 
						 | 
					@ -78,10 +81,9 @@
 | 
				
			||||||
    "rollup": "^0.67.4",
 | 
					    "rollup": "^0.67.4",
 | 
				
			||||||
    "rollup-plugin-replace": "^2.1.0",
 | 
					    "rollup-plugin-replace": "^2.1.0",
 | 
				
			||||||
    "rollup-plugin-terser": "^3.0.0",
 | 
					    "rollup-plugin-terser": "^3.0.0",
 | 
				
			||||||
    "sapper": "github:nolanlawson/sapper#for-pinafore-9",
 | 
					    "sapper": "github:nolanlawson/sapper#nolan/sw-index-html-built",
 | 
				
			||||||
    "serve-static": "^1.13.2",
 | 
					    "serve-static": "^1.13.2",
 | 
				
			||||||
    "stringz": "^1.0.0",
 | 
					    "stringz": "^1.0.0",
 | 
				
			||||||
    "style-loader": "^0.23.1",
 | 
					 | 
				
			||||||
    "svelte": "^2.15.3",
 | 
					    "svelte": "^2.15.3",
 | 
				
			||||||
    "svelte-extras": "^2.0.2",
 | 
					    "svelte-extras": "^2.0.2",
 | 
				
			||||||
    "svelte-loader": "^2.11.0",
 | 
					    "svelte-loader": "^2.11.0",
 | 
				
			||||||
| 
						 | 
					@ -89,6 +91,7 @@
 | 
				
			||||||
    "svgo": "^1.1.1",
 | 
					    "svgo": "^1.1.1",
 | 
				
			||||||
    "terser-webpack-plugin": "^1.1.0",
 | 
					    "terser-webpack-plugin": "^1.1.0",
 | 
				
			||||||
    "tiny-queue": "^0.2.1",
 | 
					    "tiny-queue": "^0.2.1",
 | 
				
			||||||
 | 
					    "uuid": "^3.3.2",
 | 
				
			||||||
    "web-animations-js": "^2.3.1",
 | 
					    "web-animations-js": "^2.3.1",
 | 
				
			||||||
    "webpack": "^4.26.1",
 | 
					    "webpack": "^4.26.1",
 | 
				
			||||||
    "webpack-bundle-analyzer": "^3.0.3"
 | 
					    "webpack-bundle-analyzer": "^3.0.3"
 | 
				
			||||||
| 
						 | 
					@ -140,8 +143,8 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "ignore": [
 | 
					    "ignore": [
 | 
				
			||||||
      "dist",
 | 
					      "dist",
 | 
				
			||||||
      "routes/_utils/asyncModules.js",
 | 
					      "src/routes/_utils/asyncModules.js",
 | 
				
			||||||
      "routes/_components/dialog/asyncDialogs.js"
 | 
					      "src/routes/_components/dialog/asyncDialogs.js"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "esm": {
 | 
					  "esm": {
 | 
				
			||||||
| 
						 | 
					@ -154,18 +157,16 @@
 | 
				
			||||||
      "NODE_ENV": "production"
 | 
					      "NODE_ENV": "production"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "files": [
 | 
					    "files": [
 | 
				
			||||||
      "assets",
 | 
					 | 
				
			||||||
      "bin",
 | 
					      "bin",
 | 
				
			||||||
      "original-assets",
 | 
					      "inline-script.js",
 | 
				
			||||||
      "routes",
 | 
					      "original-static",
 | 
				
			||||||
      "scss",
 | 
					      "scss",
 | 
				
			||||||
      "templates",
 | 
					      "src",
 | 
				
			||||||
 | 
					      "static",
 | 
				
			||||||
      "package.json",
 | 
					      "package.json",
 | 
				
			||||||
      "package-lock.json",
 | 
					      "package-lock.json",
 | 
				
			||||||
      "server.js",
 | 
					      "webpack",
 | 
				
			||||||
      "inline-script.js",
 | 
					      "webpack.config.js"
 | 
				
			||||||
      "webpack.client.config.js",
 | 
					 | 
				
			||||||
      "webpack.server.config.js"
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
      "node": "^8.0.0"
 | 
					      "node": "^8.0.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,36 +0,0 @@
 | 
				
			||||||
<Nav {page} />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="main-content">
 | 
					 | 
				
			||||||
  <main class="{infiniteScrollPage ? 'infinite-scroll-page' : ''}">
 | 
					 | 
				
			||||||
    <slot></slot>
 | 
					 | 
				
			||||||
  </main>
 | 
					 | 
				
			||||||
  {#if !$isUserLoggedIn && page === 'home'}
 | 
					 | 
				
			||||||
    <InformationalFooter />
 | 
					 | 
				
			||||||
  {/if}
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<style>
 | 
					 | 
				
			||||||
  /* this avoids a flash of the background color when switching timelines */
 | 
					 | 
				
			||||||
  .infinite-scroll-page {
 | 
					 | 
				
			||||||
    min-height: 100vh;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
  import Nav from './Nav.html'
 | 
					 | 
				
			||||||
  import { store } from '../_store/store'
 | 
					 | 
				
			||||||
  import InformationalFooter from './InformationalFooter.html'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  export default {
 | 
					 | 
				
			||||||
    components: {
 | 
					 | 
				
			||||||
      Nav,
 | 
					 | 
				
			||||||
      InformationalFooter
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    oncreate () {
 | 
					 | 
				
			||||||
      let { page } = this.get()
 | 
					 | 
				
			||||||
      this.store.set({ currentPage: page })
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    store: () => store,
 | 
					 | 
				
			||||||
    computed: {
 | 
					 | 
				
			||||||
      infiniteScrollPage: ({ $isUserLoggedIn, page }) => $isUserLoggedIn && page !== 'settings'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
<Title name="Profile" />
 | 
					 | 
				
			||||||
<Layout page='tags'>
 | 
					 | 
				
			||||||
  <LazyPage {pageComponent} {params} />
 | 
					 | 
				
			||||||
</Layout>
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
  import Layout from '../_components/Layout.html'
 | 
					 | 
				
			||||||
  import Title from '../_components/Title.html'
 | 
					 | 
				
			||||||
  import LazyPage from '../_components/LazyPage.html'
 | 
					 | 
				
			||||||
  import pageComponent from '../_pages/accounts/[accountId].html'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  export default {
 | 
					 | 
				
			||||||
    components: {
 | 
					 | 
				
			||||||
      Layout,
 | 
					 | 
				
			||||||
      Title,
 | 
					 | 
				
			||||||
      LazyPage
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    data: () => ({
 | 
					 | 
				
			||||||
      pageComponent
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								src/client.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					import * as sapper from '../__sapper__/client.js'
 | 
				
			||||||
 | 
					import { loadPolyfills } from './routes/_utils/loadPolyfills'
 | 
				
			||||||
 | 
					import './routes/_utils/serviceWorkerClient'
 | 
				
			||||||
 | 
					import './routes/_utils/historyEvents'
 | 
				
			||||||
 | 
					import './routes/_utils/loadingMask'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					loadPolyfills().then(() => {
 | 
				
			||||||
 | 
					  console.log('init()')
 | 
				
			||||||
 | 
					  sapper.start({ target: document.querySelector('#sapper') })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (module.hot) {
 | 
				
			||||||
 | 
					  module.hot.accept()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../_api/oauth'
 | 
					import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../_api/oauth'
 | 
				
			||||||
import { getInstanceInfo } from '../_api/instance'
 | 
					import { getInstanceInfo } from '../_api/instance'
 | 
				
			||||||
import { goto } from 'sapper/runtime.js'
 | 
					import { goto } from '../../../__sapper__/client'
 | 
				
			||||||
import { switchToTheme } from '../_utils/themeEngine'
 | 
					import { switchToTheme } from '../_utils/themeEngine'
 | 
				
			||||||
import { store } from '../_store/store'
 | 
					import { store } from '../_store/store'
 | 
				
			||||||
import { updateVerifyCredentialsForInstance } from './instances'
 | 
					import { updateVerifyCredentialsForInstance } from './instances'
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import { getVerifyCredentials } from '../_api/user'
 | 
				
			||||||
import { store } from '../_store/store'
 | 
					import { store } from '../_store/store'
 | 
				
			||||||
import { switchToTheme } from '../_utils/themeEngine'
 | 
					import { switchToTheme } from '../_utils/themeEngine'
 | 
				
			||||||
import { toast } from '../_utils/toast'
 | 
					import { toast } from '../_utils/toast'
 | 
				
			||||||
import { goto } from 'sapper/runtime.js'
 | 
					import { goto } from '../../../__sapper__/client'
 | 
				
			||||||
import { cacheFirstUpdateAfter } from '../_utils/sync'
 | 
					import { cacheFirstUpdateAfter } from '../_utils/sync'
 | 
				
			||||||
import { getInstanceInfo } from '../_api/instance'
 | 
					import { getInstanceInfo } from '../_api/instance'
 | 
				
			||||||
import { database } from '../_database/database'
 | 
					import { database } from '../_database/database'
 | 
				
			||||||
| 
						 | 
					@ -32,8 +32,8 @@
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
  import { store } from '../_store/store'
 | 
					  import { store } from '../_store/store'
 | 
				
			||||||
  import LoadingPage from '../_components/LoadingPage.html'
 | 
					  import LoadingPage from './LoadingPage.html'
 | 
				
			||||||
  import AccountSearchResult from '../_components/search/AccountSearchResult.html'
 | 
					  import AccountSearchResult from './search/AccountSearchResult.html'
 | 
				
			||||||
  import { toast } from '../_utils/toast'
 | 
					  import { toast } from '../_utils/toast'
 | 
				
			||||||
  import { on } from '../_utils/eventBus'
 | 
					  import { on } from '../_utils/eventBus'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
<!-- toggled in 2xx.html based on whether the user is logged in or not -->
 | 
					<!-- toggled in template.html based on whether the user is logged in or not -->
 | 
				
			||||||
<div class="hidden-from-ssr">
 | 
					<div class="hidden-from-ssr">
 | 
				
			||||||
  <slot></slot>
 | 
					  <slot></slot>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
  <svelte:component this={pageComponent} {params} />
 | 
					  <svelte:component this={pageComponent} {params} />
 | 
				
			||||||
{/if}
 | 
					{/if}
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
					  import { doubleRAF } from '../_utils/doubleRAF'
 | 
				
			||||||
  // On the very first page load, avoid doing a "reveal" because
 | 
					  // On the very first page load, avoid doing a "reveal" because
 | 
				
			||||||
  // it leads to a flash between when the SSR is shown, the two frame we hide it,
 | 
					  // it leads to a flash between when the SSR is shown, the two frame we hide it,
 | 
				
			||||||
  // and then when we show it again.
 | 
					  // and then when we show it again.
 | 
				
			||||||
| 
						 | 
					@ -13,11 +14,9 @@
 | 
				
			||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
    oncreate () {
 | 
					    oncreate () {
 | 
				
			||||||
      firstTime = false
 | 
					      firstTime = false
 | 
				
			||||||
      requestAnimationFrame(() => {
 | 
					      // Yes, triple raf. This is to ensure the NavItem animation plays before we
 | 
				
			||||||
        requestAnimationFrame(() => {
 | 
					      // start rendering the new page.
 | 
				
			||||||
          this.set({ revealed: true })
 | 
					      doubleRAF(() => requestAnimationFrame(() => this.set({ revealed: true })))
 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    data: () => ({
 | 
					    data: () => ({
 | 
				
			||||||
      revealed: !process.browser || firstTime
 | 
					      revealed: !process.browser || firstTime
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 443 B  |