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 |
927
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 |