Add manifest.json, icons and install button, flatten client/src
This commit is contained in:
parent
a219e689c1
commit
474afda9c2
File diff suppressed because one or more lines are too long
@ -723,6 +723,7 @@ input.message-input-nick.invalid {
|
|||||||
.settings {
|
.settings {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
max-width: 692px;
|
max-width: 692px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section {
|
.settings-section {
|
||||||
@ -730,6 +731,7 @@ input.message-input-nick.invalid {
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings .checkbox {
|
.settings .checkbox {
|
||||||
@ -773,6 +775,17 @@ input.message-input-nick.invalid {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-install {
|
||||||
|
padding: 0 15px;
|
||||||
|
width: auto !important;
|
||||||
|
margin: 20px;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-install h2 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 906px) {
|
@media (max-width: 906px) {
|
||||||
.settings-file {
|
.settings-file {
|
||||||
display: block;
|
display: block;
|
||||||
@ -867,4 +880,8 @@ input.message-input-nick.invalid {
|
|||||||
.settings-section {
|
.settings-section {
|
||||||
margin-left: 50px;
|
margin-left: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-install {
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
}
|
}
|
@ -60,19 +60,19 @@ function config() {
|
|||||||
return gulp.src('../config.default.toml').pipe(gulp.dest('dist'));
|
return gulp.src('../config.default.toml').pipe(gulp.dest('dist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function fonts() {
|
function public() {
|
||||||
return gulp.src('src/font/*(*.woff|*.woff2)').pipe(gulp.dest('dist/font'));
|
return gulp.src('public/**/*').pipe(gulp.dest('dist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function compress() {
|
function compress() {
|
||||||
return gulp
|
return gulp
|
||||||
.src(['dist/**/!(*.dev.js|*.map|*.toml|*.json|*.woff|*.woff2)'])
|
.src(['dist/**/*(*.js|*.css|*.json)', '!dist/**/*(*.dev.js)'])
|
||||||
.pipe(brotli({ quality: 11 }))
|
.pipe(brotli({ quality: 11 }))
|
||||||
.pipe(gulp.dest('dist'));
|
.pipe(gulp.dest('dist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
return del(['dist/**/*(*.js|*.css|*.map)']);
|
return del(['dist/**/*(*.js|*.css|*.json|*.map)']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindata(cb) {
|
function bindata(cb) {
|
||||||
@ -120,13 +120,13 @@ function serve() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const assets = gulp.parallel(js, config, fonts);
|
const assets = gulp.parallel(js, config, public);
|
||||||
|
|
||||||
const build = gulp.series(clean, assets, compress, cleanup, bindata);
|
const build = gulp.series(clean, assets, compress, cleanup, bindata);
|
||||||
|
|
||||||
const dev = gulp.series(
|
const dev = gulp.series(
|
||||||
clean,
|
clean,
|
||||||
gulp.parallel(serve, fonts, gulp.series(config, bindata))
|
gulp.parallel(serve, public, gulp.series(config, bindata))
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task('build', build);
|
gulp.task('build', build);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import Navicon from 'containers/Navicon';
|
import Navicon from 'containers/Navicon';
|
||||||
import Button from 'components/ui/Button';
|
import Button from 'components/ui/Button';
|
||||||
import Checkbox from 'components/ui/Checkbox';
|
import Checkbox from 'components/ui/Checkbox';
|
||||||
@ -6,19 +6,35 @@ import FileInput from 'components/ui/FileInput';
|
|||||||
|
|
||||||
const Settings = ({
|
const Settings = ({
|
||||||
settings,
|
settings,
|
||||||
|
installable,
|
||||||
setSetting,
|
setSetting,
|
||||||
onCertChange,
|
onCertChange,
|
||||||
onKeyChange,
|
onKeyChange,
|
||||||
|
onInstall,
|
||||||
uploadCert
|
uploadCert
|
||||||
}) => {
|
}) => {
|
||||||
const status = settings.uploadingCert ? 'Uploading...' : 'Upload';
|
const status = settings.uploadingCert ? 'Uploading...' : 'Upload';
|
||||||
const error = settings.certError;
|
const error = settings.certError;
|
||||||
|
|
||||||
|
const handleInstallClick = useCallback(
|
||||||
|
async () => {
|
||||||
|
installable.prompt();
|
||||||
|
await installable.userChoice;
|
||||||
|
onInstall();
|
||||||
|
},
|
||||||
|
[installable]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-container">
|
<div className="settings-container">
|
||||||
<div className="settings">
|
<div className="settings">
|
||||||
<Navicon />
|
<Navicon />
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
|
{installable && (
|
||||||
|
<Button className="button-install" onClick={handleInstallClick}>
|
||||||
|
<h2>Install</h2>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<div className="settings-section">
|
<div className="settings-section">
|
||||||
<h2>Visuals</h2>
|
<h2>Visuals</h2>
|
||||||
<Checkbox
|
<Checkbox
|
@ -1,5 +1,6 @@
|
|||||||
import { createStructuredSelector } from 'reselect';
|
import { createStructuredSelector } from 'reselect';
|
||||||
import Settings from 'components/pages/Settings';
|
import Settings from 'components/pages/Settings';
|
||||||
|
import { appSet } from 'state/app';
|
||||||
import {
|
import {
|
||||||
getSettings,
|
getSettings,
|
||||||
setSetting,
|
setSetting,
|
||||||
@ -10,14 +11,16 @@ import {
|
|||||||
import connect from 'utils/connect';
|
import connect from 'utils/connect';
|
||||||
|
|
||||||
const mapState = createStructuredSelector({
|
const mapState = createStructuredSelector({
|
||||||
settings: getSettings
|
settings: getSettings,
|
||||||
|
installable: state => state.app.installable
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatch = {
|
const mapDispatch = {
|
||||||
onCertChange: setCert,
|
onCertChange: setCert,
|
||||||
onKeyChange: setKey,
|
onKeyChange: setKey,
|
||||||
uploadCert,
|
uploadCert,
|
||||||
setSetting
|
setSetting,
|
||||||
|
onInstall: () => appSet('installable', null)
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
@ -25,6 +25,11 @@ runModules({ store, socket });
|
|||||||
|
|
||||||
createRoot(document.getElementById('root')).render(<Root store={store} />);
|
createRoot(document.getElementById('root')).render(<Root store={store} />);
|
||||||
|
|
||||||
|
window.addEventListener('beforeinstallprompt', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
store.dispatch(appSet('installable', e));
|
||||||
|
});
|
||||||
|
|
||||||
register({
|
register({
|
||||||
onUpdate: () => store.dispatch(appSet('newVersionAvailable', true))
|
onUpdate: () => store.dispatch(appSet('newVersionAvailable', true))
|
||||||
});
|
});
|
@ -23,7 +23,8 @@ const initialState = {
|
|||||||
showDetails: false
|
showDetails: false
|
||||||
},
|
},
|
||||||
hexIP: false,
|
hexIP: false,
|
||||||
newVersionAvailable: false
|
newVersionAvailable: false,
|
||||||
|
installable: null
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createReducer(initialState, {
|
export default createReducer(initialState, {
|
@ -54,7 +54,6 @@
|
|||||||
"webpack": "^4.25.1",
|
"webpack": "^4.25.1",
|
||||||
"webpack-dev-middleware": "^3.4.0",
|
"webpack-dev-middleware": "^3.4.0",
|
||||||
"webpack-hot-middleware": "^2.24.3",
|
"webpack-hot-middleware": "^2.24.3",
|
||||||
"webpack-manifest-plugin": "^2.0.4",
|
|
||||||
"workbox-webpack-plugin": "^3.6.3"
|
"workbox-webpack-plugin": "^3.6.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -92,10 +91,10 @@
|
|||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"^components(.*)$": "<rootDir>/src/js/components$1",
|
"^components(.*)$": "<rootDir>/js/components$1",
|
||||||
"^containers(.*)$": "<rootDir>/src/js/containers$1",
|
"^containers(.*)$": "<rootDir>/js/containers$1",
|
||||||
"^state(.*)$": "<rootDir>/src/js/state$1",
|
"^state(.*)$": "<rootDir>/js/state$1",
|
||||||
"^utils(.*)$": "<rootDir>/src/js/utils$1"
|
"^utils(.*)$": "<rootDir>/js/utils$1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
client/public/favicon.ico
Normal file
BIN
client/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
BIN
client/public/icon_192.png
Normal file
BIN
client/public/icon_192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
client/public/icon_512.png
Normal file
BIN
client/public/icon_512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
21
client/public/manifest.json
Normal file
21
client/public/manifest.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short_name": "Dispatch",
|
||||||
|
"name": "Dispatch",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icon_192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icon_512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "/",
|
||||||
|
"background_color": "#f0f0f0",
|
||||||
|
"display": "standalone",
|
||||||
|
"scope": "/",
|
||||||
|
"theme_color": "#f0f0f0"
|
||||||
|
}
|
@ -4,17 +4,17 @@ var postcssPresetEnv = require('postcss-preset-env');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
entry: ['webpack-hot-middleware/client', './src/js/index'],
|
entry: ['webpack-hot-middleware/client', './js/index'],
|
||||||
output: {
|
output: {
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
publicPath: '/'
|
publicPath: '/'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
components: path.resolve(__dirname, 'src/js/components'),
|
components: path.resolve(__dirname, 'js/components'),
|
||||||
containers: path.resolve(__dirname, 'src/js/containers'),
|
containers: path.resolve(__dirname, 'js/containers'),
|
||||||
state: path.resolve(__dirname, 'src/js/state'),
|
state: path.resolve(__dirname, 'js/state'),
|
||||||
utils: path.resolve(__dirname, 'src/js/utils')
|
utils: path.resolve(__dirname, 'js/utils')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user