Thumbnail doubles up as secondary loader; Webpack dev server as primary dev stack, dynamic base_href to accommodate
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -99,7 +99,7 @@ jobs:
|
|||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- name: Build JS
|
- name: Build JS
|
||||||
run: npm run build:prod
|
run: npm run prod
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
|
|||||||
@ -13,7 +13,6 @@ var path = require('path');
|
|||||||
var rimraf = require('rimraf');
|
var rimraf = require('rimraf');
|
||||||
var copydir = require('copy-dir');
|
var copydir = require('copy-dir');
|
||||||
var copyfile = require('fs-copy-file');
|
var copyfile = require('fs-copy-file');
|
||||||
|
|
||||||
var version = fs.readFileSync("IRIS_VERSION", "utf8");
|
var version = fs.readFileSync("IRIS_VERSION", "utf8");
|
||||||
version = version.replace(/\r?\n?/g, '').trim();
|
version = version.replace(/\r?\n?/g, '').trim();
|
||||||
var build = Math.floor(Date.now() / 1000);
|
var build = Math.floor(Date.now() / 1000);
|
||||||
|
|||||||
10
package.json
10
package.json
@ -95,14 +95,12 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"tox": "sudo docker exec -it -u root iris_mopidy_1 bash -c \"cd /iris && tox\"",
|
"tox": "sudo docker exec -it -u root iris_mopidy_1 bash -c \"cd /iris && tox\"",
|
||||||
"start": "node build_tools/build.js && NODE_ENV=development webpack-dev-server",
|
"start": "NODE_ENV=development webpack-dev-server",
|
||||||
"lint": "eslint src",
|
"lint": "eslint src",
|
||||||
"lint:fix": "eslint src --fix",
|
"lint:fix": "eslint src --fix",
|
||||||
"watch:dev": "node build_tools/build.js && NODE_ENV=development webpack --watch",
|
"build": "node build_tools/build.js",
|
||||||
"watch:prod": "node build_tools/build.js && NODE_ENV=production webpack --watch",
|
"dev": "node build_tools/build.js && NODE_ENV=development webpack",
|
||||||
"build:tools": "node build_tools/build.js",
|
"prod": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack",
|
||||||
"build:dev": "node build_tools/build.js && NODE_ENV=development webpack",
|
|
||||||
"build:prod": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack",
|
|
||||||
"release": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack && python setup.py sdist upload -r pypi && build_tools/release.sh"
|
"release": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack && python setup.py sdist upload -r pypi && build_tools/release.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
227
src/index.html
227
src/index.html
@ -1,118 +1,123 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<title>Iris</title>
|
||||||
<title>Iris</title>
|
<base id="base_href" href="/iris/" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
<meta name="apple-mobile-web-app-title" content="Iris" />
|
||||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="#121212" />
|
||||||
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
<link rel="manifest" href="manifest.json" crossorigin="use-credentials" />
|
<meta name="theme-color" content="#222222" />
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
<!-- App setup -->
|
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Iris" />
|
<style>
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
html {
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="#121212" />
|
background-color: #121212;
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
}
|
||||||
<meta name="theme-color" content="#222222" />
|
@keyframes loader {
|
||||||
|
0% { left: 0; right: 100%; }
|
||||||
<!-- Icons -->
|
50% { left: 0; right: 0; }
|
||||||
<link rel="apple-touch-startup-image" href="assets/app-icon_512.png" />
|
100% { left: 100%; right: 0; }
|
||||||
<link rel="apple-touch-icon" sizes="192x192" href="assets/app-icon_192.png" />
|
}
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="assets/app-icon_512.png" />
|
#app-loading {
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="assets/app-icon_57.png">
|
position: fixed;
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="assets/app-icon_60.png">
|
top: 50vh;
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="assets/app-icon_72.png">
|
left: 0;
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="assets/app-icon_76.png">
|
right: 0;
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="assets/app-icon_114.png">
|
transform: translateY(-50%);
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="assets/app-icon_120.png">
|
text-align: center;
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="assets/app-icon_144.png">
|
padding: 30px 0;
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="assets/app-icon_152.png">
|
}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/app-icon_180.png">
|
#app-loading-logo {
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
<link class="favicon" rel="shortcut icon" type="image/ico" href="assets/favicon.png" />
|
margin: 0 auto;
|
||||||
<link class="favicon" rel="shortcut icon" type="image/x-icon" href="assets/favicon.png" />
|
display: block;
|
||||||
<link class="favicon" rel="shortcut-icon" href="assets/favicon.png" />
|
width: 60vw;
|
||||||
|
max-width: 100px;
|
||||||
<link rel="mask-icon" href="assets/app-icon.svg" color="#08d58f" />
|
opacity: 0.25;
|
||||||
|
}
|
||||||
<!-- Loading screen styles -->
|
#app-loading-loader.loading {
|
||||||
<style>
|
position: relative;
|
||||||
html {
|
margin: 30px auto 0;
|
||||||
background-color: #121212;
|
width: 80vw;
|
||||||
|
max-width: 200px;
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #1A1A1A;
|
||||||
|
}
|
||||||
|
#app-loading-loader.loading::before {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
content: '';
|
||||||
|
height: 100%;
|
||||||
|
animation-name: loader;
|
||||||
|
background: #444444;
|
||||||
|
animation-duration: 1.8s;
|
||||||
|
animation-timing-function: ease-in-out;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
#app-loading-message {
|
||||||
|
color: white;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var base_href = document.location.pathname.indexOf('/iris/') > -1 ? '/iris/' : '/';
|
||||||
|
const baseObject = document.getElementById('base_href');
|
||||||
|
baseObject.href = base_href;
|
||||||
|
|
||||||
|
var links = [
|
||||||
|
{ rel: 'manifest', href: 'manifest.json', crossorigin: 'use-credentials' },
|
||||||
|
{ rel: 'apple-touch-startup-image', href: 'assets/app-icon_512.png' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_192.png', sizes: '192x192' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_512.png', sizes: '512x512' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_57.png', sizes: '57x57' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_60.png', sizes: '60x60' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_72.png', sizes: '72x72' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_76.png', sizes: '76x76' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_114.png', sizes: '114x114' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_120.png', sizes: '120x120' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_144.png', sizes: '144x144' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_152.png', sizes: '152x152' },
|
||||||
|
{ rel: 'apple-touch-icon', href: 'assets/app-icon_180.png', sizes: '180x180' },
|
||||||
|
{ rel: 'shortcut icon', href: 'assets/favicon.png', class: 'favicon', type: 'image/ico' },
|
||||||
|
{ rel: 'shortcut icon', href: 'assets/favicon.png', class: 'favicon', type: 'image/x-icon' },
|
||||||
|
{ rel: 'shortcut-icon', href: 'assets/favicon.png', class: 'favicon' },
|
||||||
|
{ rel: 'mask-icon', href: 'assets/app-icon.svg', color: '#08d58f' },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const link of links) {
|
||||||
|
const linkObject = document.createElement('link');
|
||||||
|
linkObject.rel = link.rel;
|
||||||
|
linkObject.href = base_href + link.href;
|
||||||
|
if (link.type) linkObject.type = link.type;
|
||||||
|
if (link.sizes) linkObject.sizes = link.sizes;
|
||||||
|
if (link.color) linkObject.color = link.color;
|
||||||
|
if (link.crossorigin) linkObject.crossorigin = link.crossorigin;
|
||||||
|
document.head.appendChild(linkObject);
|
||||||
}
|
}
|
||||||
@keyframes loader {
|
</script>
|
||||||
0% { left: 0; right: 100%; }
|
<body>
|
||||||
50% { left: 0; right: 0; }
|
<div id="app">
|
||||||
100% { left: 100%; right: 0; }
|
<!-- ReactJS app gets injected here, replacing the loader -->
|
||||||
}
|
<div id="app-loading">
|
||||||
#app-loading {
|
<img src="assets/app-icon.svg" id="app-loading-logo" />
|
||||||
position: fixed;
|
<div id="app-loading-loader" class="loading"></div>
|
||||||
top: 50vh;
|
<div id="app-loading-message">
|
||||||
left: 0;
|
<div id="app-loading-message-base"></div>
|
||||||
right: 0;
|
<div id="app-loading-message-js"></div>
|
||||||
transform: translateY(-50%);
|
<div id="app-loading-message-css"></div>
|
||||||
text-align: center;
|
</div>
|
||||||
padding: 30px 0;
|
|
||||||
}
|
|
||||||
#app-loading-logo {
|
|
||||||
filter: brightness(0) invert(1);
|
|
||||||
margin: 0 auto;
|
|
||||||
display: block;
|
|
||||||
width: 60vw;
|
|
||||||
max-width: 100px;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
#app-loading-loader.loading {
|
|
||||||
position: relative;
|
|
||||||
margin: 30px auto 0;
|
|
||||||
width: 80vw;
|
|
||||||
max-width: 200px;
|
|
||||||
height: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #1A1A1A;
|
|
||||||
}
|
|
||||||
#app-loading-loader.loading::before {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
content: '';
|
|
||||||
height: 100%;
|
|
||||||
animation-name: loader;
|
|
||||||
background: #444444;
|
|
||||||
animation-duration: 1.8s;
|
|
||||||
animation-timing-function: ease-in-out;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
#app-loading-message {
|
|
||||||
color: white;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 10px;
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="app">
|
|
||||||
<!-- ReactJS app gets injected here, replacing the loader -->
|
|
||||||
<div id="app-loading">
|
|
||||||
<img src="assets/app-icon.svg" id="app-loading-logo" />
|
|
||||||
<div id="app-loading-loader" class="loading"></div>
|
|
||||||
<div id="app-loading-message">
|
|
||||||
<div id="app-loading-message-base"></div>
|
|
||||||
<div id="app-loading-message-js"></div>
|
|
||||||
<div id="app-loading-message-css"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if ('serviceWorker' in navigator){
|
if ('serviceWorker' in navigator){
|
||||||
navigator.serviceWorker.register('/service-worker.js')
|
navigator.serviceWorker.register('/service-worker.js')
|
||||||
@ -123,7 +128,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var setMessage = function(type = '', content = '') {
|
var setMessage = function(type = '', content = '') {
|
||||||
var element = document.getElementById(`app-loading-message-${type}`);
|
var element = document.getElementById(`app-loading-message-${type}`);
|
||||||
@ -196,6 +200,5 @@
|
|||||||
document.body.appendChild(js);
|
document.body.appendChild(js);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,7 @@ export default memo((props) => {
|
|||||||
style={{ backgroundImage: `url("${image}")` }}
|
style={{ backgroundImage: `url("${image}")` }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Loader loading={loading} />
|
{loading && <Loader loading />}
|
||||||
<div className="thumbnail__actions">
|
<div className="thumbnail__actions">
|
||||||
{props.canZoom && image && (
|
{props.canZoom && image && (
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@ -36,10 +36,10 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 8;
|
z-index: 8;
|
||||||
background-color: rgba(0, 0, 0, 0.50);
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
|
||||||
@include theme('light') {
|
@include theme('light') {
|
||||||
background-color: rgba(255, 255, 255, 0.50);
|
background-color: rgba(255, 255, 255, 0.75);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ const config = {
|
|||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: `app${isDev ? '' : '.min'}.css`,
|
filename: `app${isDev ? '' : '.min'}.css`,
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({ template: './mopidy_iris/static/index.html' }),
|
new HtmlWebpackPlugin({ template: './src/index.html' }),
|
||||||
],
|
],
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
poll: true,
|
poll: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user