diff --git a/.gitignore b/.gitignore index 5a8c9b2..5cbb075 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,11 @@ cameras.sql +.DS_Store .project .settings *.swp node_modules prep.config +settings-nvr-local.js target ui-dist yarn-error.log diff --git a/README.md b/README.md index 65405fe..7a25ecd 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ make this possible: * [License](LICENSE.txt) — GPLv3 * [Building and installing](guide/install.md) +* [UI Development](guide/developing-ui.md) * [Troubleshooting](guide/troubleshooting.md) # Getting help and getting involved diff --git a/guide/developing-ui.md b/guide/developing-ui.md new file mode 100644 index 0000000..c9d5d67 --- /dev/null +++ b/guide/developing-ui.md @@ -0,0 +1,146 @@ +# Working on UI development + +The UI is presented from a single HTML page (index.html) and any number +of Javascript files, css files, images, etc. These are "packed" together +using [webpack](https://webpack.js.org). + +For ongoing development it is possible to have the UI running in a web +browser using "hot loading". This means that as you make changes to source +files, they will be detected, the webpack will be recompiled and generated +and then the browser will be informed to reload things. In combination with +the debugger built into modern browsers this makes for a reasonable process. + +For a production build, the same process is followed, except with different +settings. In particular, no hot loading development server will be started +and more effort is expended on packing and minimizing the components of +the application as represented in the various "bundles". Read more about +this in the webpack documentation. + +## Getting started + +Checkout the branch you want to work on and type + + $ yarn start + +This will pack and prepare a development setup. By default the development +server that serves up the web page(s) will listen on +[http://localhost:3000](http://localhost:3000) so you can direct your browser +there. + +Make any changes to the source code as you desire (look at existing code +for examples and typical style), and the browser will hot-load your changes. +Often times you will make mistakes. Anything from a coding error (for which +you can use the browser's debugger), or compilation breaking Javascript errors. +The latter will often be reported as errors during the webpack assembly +process, but some will show up in the browser console, or both. + +## Control and location of settings + +Much of the settings needed to put the UI together, run webpack etc. is +located in a series of files that contain webpack configuration. These +files all live in the "webpack" subdirectory. We will not explain all +of them here, as you should rarely need to understand them, let alone +modify them. + +What is worth mentioning is that the `package.json` file is configured +to use a different webpack configuration for development vs. production +builds. Both configurations depend on a shared configuration common to +both. + +There are also some settings that control aspects of the MoonFire UI +behavior, such as window titles etc. These settings are found in the +`settings-nvr.js` file in the project root directory. They should be +pretty self explanatory. + +The webpack configuration for all webpack builds is able to load the +values from `settings-nvr.js` and then, if the file exists, load those +from `settings-nvr-local.js` and use them to add to the configuration, +or replace. You can take advantage of this to add your own configuration +values in the "local" file, which does not get checked in, but is used +to affect development, and production builds. + +## Special considerations for API calls + +The UI code will make calls to the MoonFire NVR's server API, which is +assumed to run on the same host as the MoonFire server. This makes sense +because that server is also normally the one serving up the UI. For UI +development, however this is not always convenient, or even useful. + +For one, you may be doing this development on a machine other than where +the main MoonFire server is running. That can work, but of course that +machine will not be responding the the API calls. If the UI does not +gracefully handle API failure errors (it should but development on that +is ongoing), it may break your UI code. + +Therefore, for practical purposes, you may want the API calls to go to +a different server than where the localhost is. Rather than editing the +`webpack/dev.conf.js` file to make this happen, you should use a different +mechanism. The reason for not modifying this file (unless the change is +needed by all), is that the file is under source control and thus should +not reflect settings that are just for your personal use. + +The manner in which you can achieve using a different server for API +calls is by telling the development server to use a "proxy" for +certain urls. All API calls start with "/api", so we'll take advantage +of that. Create a the file `settings-nvr-local.js` right next to the standard +`settings-nvr.js`. The file should look something like this: + + module.exports.settings = { + devServer: { + proxy: { + '/api': 'http://192.168.1.232:8080' + } + } + }; + +This tells the development server to proxy all urls that it encounters +requests for to the url specified. The way this is done is by taking the +full URI component for the original request, and appending it to the string +configured on the right side of the path to be rewritten above. In a standard +MoonFire install, the server (and thus the API server as well), will be +listening on port 8080 a the IP address where the server lives. So adjust +the above for reach your own MoonFire instance where there is a server +running with some real data behind it. + +### Issues with "older" MoonFire builds + +You might also have though to change the "/api" string in the source code +to include the IP address of the MoonFire server. This would use the +"right" (desirable) URLs, but the requests will fail due to a violation +of the Cross-Origin Resource Sharing (CORS) protocol. If you really +need to, you can add a configuration option to the MoonFire server +by modifying its "service definition". We will not explain here how. + +## Changing development server configuration + +You can find our standard configuration for the development server inside +the `webpacks/dev.conf.js` file. Using the technique outlined above you +can change ports, ip addresses etc. One example where this may come in +useful is that you may want to "test" your new API code, running on +machine "A" (from a development server), proxying API requests to machine +"B" (because it has real data), from a browser running on machine "C". + +The development server normally is configured to listing on port 3000 +on "localhost." (which would correspond to machine "A" in this example). +However, you cannot use "localhost" on another machine to refer to "A". +You may think that using the IP address of "A" works, but it doesn't +because "localhost" lives at an IP address local to machine "A". + +To make this work you must tell the development server on host "A" to +listen differently. You need to configure it to listen on IP address +"0.0.0.0", which means "all available interfaces". Once that is in +place you can use the IP address to reach "A" from "C". "A" will then +send API requests on to "B", and present final UI using information +from "A" and "B" to the browser on "C". + +Modify the local settings to something like this: + + module.exports.settings = { + devServer: { + host: "0.0.0.0", + proxy: { + '/api': 'http://192.168.1.232:8080' + } + } + }; + diff --git a/guide/easy-install.md b/guide/easy-install.md index fbee383..9702357 100644 --- a/guide/easy-install.md +++ b/guide/easy-install.md @@ -4,7 +4,7 @@ There are no binary packages of Moonfire NVR available yet, so it must be built from source. This is made easy using a few scripts that will do the job for you unless you have very a different operating system. The scripts are written and tested under ubuntu and raspbian but should not be hard to modify if necessary. -You'll start by downloading moonfire if you have not already done so. +You'll start by downloading Moonfire if you have not already done so. ## Downloading @@ -55,12 +55,12 @@ hard disk. Start by executing the setup script: - $ cd moonfire-nr + $ cd moonfire-nvr $ scripts/setup-ubuntu.sh If this is the very first time you run this script, a file named `prep.config` will be created and the script will stop. This file is where you will set -or change variables that describe the moonfire installation you want. The +or change variables that describe the Moonfire installation you want. The initial execution will put default values in this value, but only for the most commonly changed variables. For a full list of variables, see below. @@ -73,12 +73,12 @@ case you must either resolve those first, or go the manual route. The script may be given the "-f" option. If you do, you are telling the script that you do not want any existing installation of ffmpeg to be overwritten with a newer one. This could be important to you. If you do use it, and the version -you have installed is not compatible with moonfire, you will be told through +you have installed is not compatible with Moonfire, you will be told through a message. If you have no ffmpeg installed, the option is effectively ignored and the necessary version of ffmpeg will be installed. The setup script should only need to be run once (after `prep.config` has been -created), although if you do a re-install of moonfire, in particular a much +created), although if you do a re-install of Moonfire, in particular a much newer version, it is a good idea to run it again as requirements and pre-requisites may have changed. Running the script multiple times should not have any negative effects. @@ -86,7 +86,7 @@ may have changed. Running the script multiple times should not have any negative in particular during the building of libavutil you will see several compiler warnings. This, while undesirable, is a direct result of the original developers not cleaning up the cause(s) of these warnings. They are, however, -just warnings and will not affect correct functioning of moonfire. +just warnings and will not affect correct functioning of Moonfire. Once the setup is complete, two steps remain: building and then installing. There is a script for each of these scenarios, but since generally you would @@ -99,7 +99,7 @@ The build script is involved like this: $ scripts/build.sh -This script will perform all steps necessary to build a complete moonfire +This script will perform all steps necessary to build a complete Moonfire setup. If there are no build errors, this script will then automatically invoke the install script (see below). @@ -120,7 +120,7 @@ like this: This script will copy various files resulting from the build to the correct locations. It will also create a "service configuration" for systemctl that -can be used to control moonfire. This service configuration can be prevented +can be used to control Moonfire. This service configuration can be prevented by using the "-s" option to this script. It will also prevent the automatic start of this configuration. diff --git a/package.json b/package.json index 712dd9f..1552e2b 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,12 @@ }, "scripts": { "start": "webpack-dev-server --mode development --config webpack/dev.config.js --progress", - "build": "webpack --mode production --config webpack/prod.config.js && cp ui-src/index.html ui-dist/" + "build": "webpack --mode production --config webpack/prod.config.js" }, "dependencies": { "jquery": "^3.2.1", "jquery-ui": "^1.12.1", - "moment-timezone": "^0.5.13", - "webpack-merge": "^4.1.2" + "moment-timezone": "^0.5.13" }, "homepage": "https://github.com/scottlamb/moonfire-nvr", "license": "GPL-3.0", @@ -26,9 +25,11 @@ "clean-webpack-plugin": "^0.1.18", "css-loader": "^0.28.10", "file-loader": "^1.1.11", + "html-webpack-plugin": "^3.0.6", "style-loader": "^0.19.0", "webpack": "^4.0.1", "webpack-cli": "^2.0.10", - "webpack-dev-server": "^3.1.0" + "webpack-dev-server": "^3.1.0", + "webpack-merge": "^4.1.2" } } diff --git a/settings-nvr.js b/settings-nvr.js new file mode 100644 index 0000000..84f8323 --- /dev/null +++ b/settings-nvr.js @@ -0,0 +1,37 @@ +// vim: set et ts=2 sw=2: +// + +/** + * This module must export a map, but can use a function with no arguments + * that returns a map, or a function that receives the "env" and "args" + * values from webpack. + * + * @type {Object} + */ +module.exports.settings = { + // Project related: use ./ in front of project root relative files! + app_src_dir: './ui-src', + dist_dir: './ui-dist', + + // App related + app_title: 'Moonfire NVR', + + // Where is the server to be found + moonfire: { + server: 'localhost', + port: 8080, + }, + + /* + * In settings override file you can add sections like below on this level. + * After processing, anything defined in mode.production or mode.development, + * as appropriate based on --mode argument to webpack, will be merged + * into the top level of this settings module. This allows you to add to, or + * override anything listed above. + * + * webpack_mode: { + * production: {}, + * development: {}, + }, + */ +}; diff --git a/ui-src/index.html b/ui-src/index.html index c3b4590..96a3e4f 100644 --- a/ui-src/index.html +++ b/ui-src/index.html @@ -2,16 +2,14 @@
-