diff --git a/README.md b/README.md
index d1171b0..a3193fa 100644
--- a/README.md
+++ b/README.md
@@ -336,6 +336,11 @@ When using Docker:
* **Static deployment**: Mount your `custom.js` file to `/usr/share/nginx/html/scripts/custom.js`
* **Server deployment**: Mount your `custom.js` file to `/app/server/scripts/custom.js`
+### Custom text scroll
+If you would like your Weatherstar to have custom scrolling text in the bottom blue bar, turn on the setting for `Enable RSS Feed/Text` and then enter text in the resulting text box. Then press set.
+
+Tip: You can have Weatherstar select randomly between several text strings on each pass through the current conditions. Use a pipe character to separate string. `Welcome to Weatherstar|Thanks for watching`.
+
## Issue reporting and feature requests
Please do not report issues with api.weather.gov being down. It's a new service and not considered fully operational yet. I've also observed that the API can go down on a regional basis (based on NWS office locations). This means that you may have problems getting data for, say, Chicago right now, but Dallas and others are working just fine.
diff --git a/gulp/publish-frontend.mjs b/gulp/publish-frontend.mjs
index ed83fdd..151a4cd 100644
--- a/gulp/publish-frontend.mjs
+++ b/gulp/publish-frontend.mjs
@@ -86,6 +86,7 @@ const mjsSources = [
'server/scripts/modules/travelforecast.mjs',
'server/scripts/modules/progress.mjs',
'server/scripts/modules/media.mjs',
+ 'server/scripts/modules/custom-scroll-text.mjs',
'server/scripts/index.mjs',
];
diff --git a/server/scripts/modules/custom-scroll-text.mjs b/server/scripts/modules/custom-scroll-text.mjs
new file mode 100644
index 0000000..7d8cc7f
--- /dev/null
+++ b/server/scripts/modules/custom-scroll-text.mjs
@@ -0,0 +1,91 @@
+import Setting from './utils/setting.mjs';
+import { reset as resetScroll, addScreen as addScroll, hazards } from './currentweatherscroll.mjs';
+
+let firstRun = true;
+
+const parser = new DOMParser();
+
+// change of enable handler
+const changeEnable = (newValue) => {
+ let newDisplay;
+ if (newValue) {
+ // add the text to the scroll
+ parseText(customText.value);
+ // show the string box
+ newDisplay = 'block';
+ } else {
+ // set scroll back to original
+ resetScroll();
+ // hide the string entry
+ newDisplay = 'none';
+ }
+ const stringEntry = document.getElementById('settings-customText-label');
+ if (stringEntry) {
+ stringEntry.style.display = newDisplay;
+ }
+};
+
+// parse the text provided
+const parseText = (textInput) => {
+ // skip updating text on first run
+ if (firstRun) return;
+
+ // test validity
+ if (textInput === undefined || textInput === '') {
+ resetScroll();
+ }
+
+ // split the text at pipe characters
+ const texts = textInput.split('|');
+
+ // add single text scroll after hazards if present
+ resetScroll();
+ addScroll(hazards);
+ addScroll(
+ () => {
+ // pick a random string from the available list
+ const randInt = Math.floor(Math.random() * texts.length);
+ return {
+ type: 'scroll',
+ text: texts[randInt],
+ };
+ },
+ // keep the existing scroll
+ true,
+ );
+};
+
+// change the text
+const changeText = (newValue) => {
+ // first pass through won't have custom text enable ready
+ if (firstRun) return;
+
+ if (customTextEnable.value) {
+ parseText(newValue);
+ }
+};
+
+const customText = new Setting('customText', {
+ name: 'Custom Text',
+ defaultValue: '',
+ type: 'string',
+ changeAction: changeText,
+ placeholder: 'Text to scroll',
+});
+
+const customTextEnable = new Setting('customTextEnable', {
+ name: 'Enable Custom Text',
+ defaultValue: false,
+ changeAction: changeEnable,
+});
+
+// initialize the custom text inputs on the page
+document.addEventListener('DOMContentLoaded', () => {
+ // add the controls to the page
+ const settingsSection = document.querySelector('#settings');
+ settingsSection.append(customTextEnable.generate(), customText.generate());
+ // clear the first run value
+ firstRun = false;
+ // call change enable with the current value to show/hide the url box
+ changeEnable(customTextEnable.value);
+});
diff --git a/views/index.ejs b/views/index.ejs
index 73fb8f1..c4c022d 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -62,6 +62,7 @@
+
<% } %>