diff --git a/cpp/server/content_type_map.cpp b/cpp/server/content_type_map.cpp index a863bcb1..5708d3d2 100644 --- a/cpp/server/content_type_map.cpp +++ b/cpp/server/content_type_map.cpp @@ -37,6 +37,7 @@ ContentTypeMap::ContentTypeMap() add(ContentType::TEXT_CSS, "css"); add(ContentType::APPLICATION_JAVASCRIPT, "js"); add(ContentType::APPLICATION_JSON, "json"); + add(ContentType::APPLICATION_WEB_MANIFEST, "webmanifest"); add(ContentType::IMAGE_JPEG, "jpg", "jpeg"); add(ContentType::IMAGE_PNG, "png"); add(ContentType::IMAGE_GIF, "gif"); diff --git a/cpp/server/http.cpp b/cpp/server/http.cpp index 3f12be9b..a2464f91 100644 --- a/cpp/server/http.cpp +++ b/cpp/server/http.cpp @@ -46,6 +46,8 @@ const char ContentType::IMAGE_GIF[] = "image/gif"; const char ContentType::IMAGE_BMP[] = "image/bmp"; +const char ContentType::APPLICATION_WEB_MANIFEST[] = "application/manifest+json"; + std::string toString(HttpMethod method) { switch (method) diff --git a/cpp/server/http.hpp b/cpp/server/http.hpp index 1822023d..250c6046 100644 --- a/cpp/server/http.hpp +++ b/cpp/server/http.hpp @@ -61,6 +61,7 @@ struct ContentType static const char IMAGE_PNG[]; static const char IMAGE_GIF[]; static const char IMAGE_BMP[]; + static const char APPLICATION_WEB_MANIFEST[]; }; std::string toString(HttpMethod method); diff --git a/js/webui/package.json b/js/webui/package.json index d822574b..d46f5a62 100644 --- a/js/webui/package.json +++ b/js/webui/package.json @@ -31,6 +31,7 @@ "@babel/core": "^7.20.12", "@babel/preset-react": "^7.18.6", "babel-loader": "^8.3.0", + "copy-webpack-plugin": "^13.0.1", "css-loader": "^6.7.3", "css-minimizer-webpack-plugin": "^3.4.1", "file-loader": "^6.2.0", diff --git a/js/webui/src/about_box.js b/js/webui/src/about_box.js index 15c537fc..633e9d2b 100644 --- a/js/webui/src/about_box.js +++ b/js/webui/src/about_box.js @@ -2,6 +2,8 @@ import React from 'react' import ServiceContext from './service_context.js'; import ModelBinding from './model_binding.js'; +const appLogoUrl = '/logo.svg#logo'; + class AboutBox_ extends React.PureComponent { static contextType = ServiceContext; @@ -25,8 +27,14 @@ class AboutBox_ extends React.PureComponent return (
-
- Beefweb v{pluginVersion} @ {title} v{version} +
+ + + +
+
{title} v{version}
+
Beefweb v{pluginVersion}
+
Donate to author diff --git a/js/webui/src/index.html b/js/webui/src/index.html index 40682154..4c11d339 100644 --- a/js/webui/src/index.html +++ b/js/webui/src/index.html @@ -5,6 +5,8 @@ + + diff --git a/js/webui/src/setting_editor.js b/js/webui/src/setting_editor.js index cc8941b3..3016ff23 100644 --- a/js/webui/src/setting_editor.js +++ b/js/webui/src/setting_editor.js @@ -149,12 +149,12 @@ class PercentTextEditor extends React.PureComponent handleInput(e) { e.preventDefault(); - this.context.settingsModel[this.props.settingKey] = Number(e.target.value); } - handleReset() + handleReset(e) { + e.preventDefault(); this.context.settingsModel.resetValueToDefault(this.props.settingKey); } diff --git a/js/webui/src/style.less b/js/webui/src/style.less index 59e5d764..7d3b9181 100644 --- a/js/webui/src/style.less +++ b/js/webui/src/style.less @@ -887,6 +887,31 @@ body { max-width: 40rem; } +.about-box-main { + display: flex; + align-items: center; +} + +.about-box-logo { + width: 8rem; + height: 8rem; + padding: 0.25rem 0 0.25rem 0.25rem; +} + +.st-uitheme-dark .about-box-logo { + background: #ebf0ea; + border-radius: 0.125rem; +} + +.about-box-info { + margin-left: 0.5rem; + font-size: 1.2rem; + + & > div:not(:first-child) { + margin-top: 1rem; + } +} + .license-text { font-family: monospace; font-size: 110%; diff --git a/js/webui/static/logo-bg.png b/js/webui/static/logo-bg.png new file mode 100644 index 00000000..ea235da4 Binary files /dev/null and b/js/webui/static/logo-bg.png differ diff --git a/js/webui/static/logo-bg.svg b/js/webui/static/logo-bg.svg new file mode 100644 index 00000000..c76be541 --- /dev/null +++ b/js/webui/static/logo-bg.svg @@ -0,0 +1,13 @@ + + diff --git a/js/webui/static/logo.svg b/js/webui/static/logo.svg new file mode 100644 index 00000000..05789147 --- /dev/null +++ b/js/webui/static/logo.svg @@ -0,0 +1,5 @@ + + diff --git a/js/webui/svg2png.sh b/js/webui/svg2png.sh new file mode 100755 index 00000000..25138d60 --- /dev/null +++ b/js/webui/svg2png.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +cd "$(dirname $0)/static" + +convert -background none logo-bg.svg -scale 512x512 -quality 100 logo-bg.png diff --git a/js/webui/webpack.config.js b/js/webui/webpack.config.js index 1c6471d5..247eeab0 100644 --- a/js/webui/webpack.config.js +++ b/js/webui/webpack.config.js @@ -4,6 +4,7 @@ import HtmlPlugin from 'html-webpack-plugin' import MiniCssExtractPlugin from 'mini-css-extract-plugin' import CssMinimizerPlugin from 'css-minimizer-webpack-plugin' import TerserPlugin from 'terser-webpack-plugin' +import CopyPlugin from 'copy-webpack-plugin'; import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' import { buildTypes, getBuildConfig, getBuildType as resolveBuildType } from '../build_config.mjs'; @@ -56,6 +57,10 @@ function configApp(config, params) template: path.join(params.sourceDir, 'index.html') })); + config.plugins.push(new CopyPlugin({ + patterns: [{ from: params.staticDir }] + })); + if (params.analyze) { config.plugins.push(new BundleAnalyzerPlugin({ @@ -159,12 +164,14 @@ function makeBuildParams(env) outputDir = getBuildConfig(buildType).webBuildDir; const sourceDir = path.join(__dirname, 'src'); + const staticDir = path.join(__dirname, 'static'); return { buildType, enableTests: tests || false, analyze: analyze || false, sourceDir, + staticDir, outputDir, }; } diff --git a/js/yarn.lock b/js/yarn.lock index b23454f8..54bf5292 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -1088,6 +1088,17 @@ copy-anything@^2.0.1: dependencies: is-what "^3.14.1" +copy-webpack-plugin@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz#fba18c22bcab3633524e1b652580ff4489eddc0d" + integrity sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw== + dependencies: + glob-parent "^6.0.1" + normalize-path "^3.0.0" + schema-utils "^4.2.0" + serialize-javascript "^6.0.2" + tinyglobby "^0.2.12" + cross-spawn@^7.0.3: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" @@ -1575,6 +1586,13 @@ get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" @@ -1734,6 +1752,18 @@ is-core-module@^2.9.0: dependencies: has "^1.0.3" +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2011,6 +2041,11 @@ node-releases@^2.0.27, node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-url@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" @@ -2613,7 +2648,7 @@ schema-utils@^3.0.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.3: +schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== @@ -2818,7 +2853,7 @@ tinyexec@^1.0.2: resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.2.tgz#bdd2737fe2ba40bd6f918ae26642f264b99ca251" integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== -tinyglobby@^0.2.15: +tinyglobby@^0.2.12, tinyglobby@^0.2.15: version "0.2.15" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==