diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/server/bathroom-linux-amd64 b/mattermost/server/bathroom-linux-amd64
index c478ac9..673a918 100755
--- a/mattermost/server/bathroom-linux-amd64
+++ b/mattermost/server/bathroom-linux-amd64
Binary files differ
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/server/bathroom-linux-amd64 b/mattermost/server/bathroom-linux-amd64
index c478ac9..673a918 100755
--- a/mattermost/server/bathroom-linux-amd64
+++ b/mattermost/server/bathroom-linux-amd64
Binary files differ
diff --git a/mattermost/server/bathroom.go b/mattermost/server/bathroom.go
index b3512ab..7637e45 100644
--- a/mattermost/server/bathroom.go
+++ b/mattermost/server/bathroom.go
@@ -28,6 +28,7 @@
"crypto/sha1"
"path"
"encoding/base64"
+ _ "math"
)
const DO_LOGGING = false
@@ -77,6 +78,16 @@
adminUsers []string
KeyPath string
+
+ DoorNames string
+ doorNames []string
+
+ InfoIcon string
+ UnknownIcon string
+ OpenIcon string
+ ClosedIcon string
+
+ settingsJson map[string]interface{}
}
type BathroomMonitorPlugin struct {
@@ -218,6 +229,19 @@
func (p *BathroomMonitorPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
p.log(fmt.Sprintf("Requested path: %s %s", r.URL.Path, c.IpAddress))
+ if r.URL.Path == "/settings" {
+ p.configLock.Lock()
+ defer p.configLock.Unlock()
+
+ bytes, err := json.Marshal(p.config.settingsJson)
+ if err == nil {
+ fmt.Fprint(w, string(bytes))
+ } else {
+ p.API.LogError(fmt.Sprintf("Unable to json Marshal settings %s", err.Error()))
+ }
+
+ return
+ }
if r.URL.Path == "/status" {
p.doorLock.Lock()
defer p.doorLock.Unlock()
@@ -480,6 +504,36 @@
}
}
+ newConfig.doorNames = make([]string, 0, 4)
+
+ split = strings.Split(newConfig.DoorNames, "|")
+ for _, un := range split {
+ trimmed := strings.Trim(un, ", \t\n")
+ if trimmed != "" {
+ newConfig.doorNames = append(newConfig.doorNames, trimmed)
+ }
+ }
+
+ min := func(a uint8, b uint8) uint8 {
+ if a < b {
+ return a
+ }
+ return b
+ }
+
+ doorsJson := make(map[string]string)
+ for i := uint8(0); i < min(uint8(len(newConfig.doorNames)), newConfig.numDoors); i++ {
+ doorsJson[fmt.Sprintf("%d", i + 1)] = newConfig.doorNames[i]
+ }
+
+ newConfig.settingsJson = map[string]interface{} {
+ "info_icon": newConfig.InfoIcon,
+ "unknown_icon": newConfig.UnknownIcon,
+ "open_icon": newConfig.OpenIcon,
+ "closed_icon": newConfig.ClosedIcon,
+ "doors": doorsJson,
+ }
+
p.config = newConfig
p.configUpdates++
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/server/bathroom-linux-amd64 b/mattermost/server/bathroom-linux-amd64
index c478ac9..673a918 100755
--- a/mattermost/server/bathroom-linux-amd64
+++ b/mattermost/server/bathroom-linux-amd64
Binary files differ
diff --git a/mattermost/server/bathroom.go b/mattermost/server/bathroom.go
index b3512ab..7637e45 100644
--- a/mattermost/server/bathroom.go
+++ b/mattermost/server/bathroom.go
@@ -28,6 +28,7 @@
"crypto/sha1"
"path"
"encoding/base64"
+ _ "math"
)
const DO_LOGGING = false
@@ -77,6 +78,16 @@
adminUsers []string
KeyPath string
+
+ DoorNames string
+ doorNames []string
+
+ InfoIcon string
+ UnknownIcon string
+ OpenIcon string
+ ClosedIcon string
+
+ settingsJson map[string]interface{}
}
type BathroomMonitorPlugin struct {
@@ -218,6 +229,19 @@
func (p *BathroomMonitorPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
p.log(fmt.Sprintf("Requested path: %s %s", r.URL.Path, c.IpAddress))
+ if r.URL.Path == "/settings" {
+ p.configLock.Lock()
+ defer p.configLock.Unlock()
+
+ bytes, err := json.Marshal(p.config.settingsJson)
+ if err == nil {
+ fmt.Fprint(w, string(bytes))
+ } else {
+ p.API.LogError(fmt.Sprintf("Unable to json Marshal settings %s", err.Error()))
+ }
+
+ return
+ }
if r.URL.Path == "/status" {
p.doorLock.Lock()
defer p.doorLock.Unlock()
@@ -480,6 +504,36 @@
}
}
+ newConfig.doorNames = make([]string, 0, 4)
+
+ split = strings.Split(newConfig.DoorNames, "|")
+ for _, un := range split {
+ trimmed := strings.Trim(un, ", \t\n")
+ if trimmed != "" {
+ newConfig.doorNames = append(newConfig.doorNames, trimmed)
+ }
+ }
+
+ min := func(a uint8, b uint8) uint8 {
+ if a < b {
+ return a
+ }
+ return b
+ }
+
+ doorsJson := make(map[string]string)
+ for i := uint8(0); i < min(uint8(len(newConfig.doorNames)), newConfig.numDoors); i++ {
+ doorsJson[fmt.Sprintf("%d", i + 1)] = newConfig.doorNames[i]
+ }
+
+ newConfig.settingsJson = map[string]interface{} {
+ "info_icon": newConfig.InfoIcon,
+ "unknown_icon": newConfig.UnknownIcon,
+ "open_icon": newConfig.OpenIcon,
+ "closed_icon": newConfig.ClosedIcon,
+ "doors": doorsJson,
+ }
+
p.config = newConfig
p.configUpdates++
diff --git a/mattermost/webapp/dist/main.js b/mattermost/webapp/dist/main.js
index 4cca171..adb6cdf 100644
--- a/mattermost/webapp/dist/main.js
+++ b/mattermost/webapp/dist/main.js
@@ -106,9 +106,24 @@
this.state = {
doors: {}
};
+ this.settings = {};
}
componentDidMount() {
+ this.getSettings();
+ }
+
+ async getSettings() {
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/settings";
+ var res = await fetch(url);
+ this.settings = await res.json();
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.getSettings.bind(this), 5000);
+ return;
+ }
+
Registry.registerWebSocketEventHandler("custom_com.mattermost.bathroom_updated", this.updateDoors.bind(this));
this.updateDoors();
}
@@ -118,22 +133,40 @@
}
async updateDoors(msg) {
- var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
- var res = await fetch(url);
- var json = await res.json();
- this.setState({
- "doors": json
- });
+ //var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/status";
+ var res = await fetch(url);
+ var json = await res.json();
+ this.setState({
+ "doors": json
+ });
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.updateDoors.bind(this), 3000);
+ }
}
render() {
if (!this.state.doors) return;
var columns = 6;
var keys = Object.keys(this.state.doors).sort();
- var width = Math.floor(100 / columns) + "%";
+ var width = Math.floor(100 / (columns + 1)) + "%";
var widthPx = "23px";
var elems = [];
var row = [];
+ var rows = 0;
+
+ var IconImg = props => _react.default.createElement("img", {
+ src: props.src,
+ width: "100%",
+ style: {
+ "padding": "2px"
+ },
+ title: props.title
+ });
+
+ var totalRows = Math.floor(keys.length / columns) + 1;
for (var i = 0; i < keys.length
/*(Math.floor(keys.length / 6) + 1) * 6*/
@@ -141,31 +174,16 @@
var img = null;
if (i < keys.length) {
- var door = this.state.doors[keys[i]];
- var imgFile = null;
+ var key = keys[i];
+ var door = this.state.doors[key];
+ var imgFile = this.settings[door + "_icon"];
- switch (door) {
- default:
- case "unknown":
- imgFile = "/static/emoji/2753.png";
- break;
-
- case "open":
- imgFile = "/static/emoji/1f6bd.png";
- break;
-
- case "closed":
- imgFile = "/static/emoji/26d4-fe0f.png";
- break;
+ if (imgFile) {
+ img = _react.default.createElement(IconImg, {
+ src: imgFile,
+ title: this.settings.doors[key]
+ }); //img =
}
-
- img = _react.default.createElement("img", {
- src: imgFile,
- width: "100%",
- style: {
- "padding": "2px"
- }
- });
}
row.push(_react.default.createElement("td", {
@@ -173,8 +191,23 @@
}, img));
if (i % columns == columns - 1 || i == keys.length - 1) {
- elems.push(_react.default.createElement(_react.default.Fragment, null, [...row]));
+ if (rows == 0) {
+ row.unshift( //
 |
+ _react.default.createElement("td", {
+ rowspan: totalRows,
+ width: widthPx,
+ style: {
+ "color": this.props.theme.sidebarText,
+ "padding-right": "5px"
+ }
+ }, _react.default.createElement(IconImg, {
+ src: this.settings.info_icon
+ }), ":"));
+ }
+
+ elems.push(_react.default.createElement("tr", null, [...row]));
row.length = 0;
+ rows++;
}
}
@@ -188,7 +221,8 @@
}, _react.default.createElement("table", {
style: {
"margin-left": "auto",
- "margin-right": "auto"
+ "margin-right": "auto",
+ "border": "1px solid " + this.props.theme.sidebarText
}
}, elems))
);
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/server/bathroom-linux-amd64 b/mattermost/server/bathroom-linux-amd64
index c478ac9..673a918 100755
--- a/mattermost/server/bathroom-linux-amd64
+++ b/mattermost/server/bathroom-linux-amd64
Binary files differ
diff --git a/mattermost/server/bathroom.go b/mattermost/server/bathroom.go
index b3512ab..7637e45 100644
--- a/mattermost/server/bathroom.go
+++ b/mattermost/server/bathroom.go
@@ -28,6 +28,7 @@
"crypto/sha1"
"path"
"encoding/base64"
+ _ "math"
)
const DO_LOGGING = false
@@ -77,6 +78,16 @@
adminUsers []string
KeyPath string
+
+ DoorNames string
+ doorNames []string
+
+ InfoIcon string
+ UnknownIcon string
+ OpenIcon string
+ ClosedIcon string
+
+ settingsJson map[string]interface{}
}
type BathroomMonitorPlugin struct {
@@ -218,6 +229,19 @@
func (p *BathroomMonitorPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
p.log(fmt.Sprintf("Requested path: %s %s", r.URL.Path, c.IpAddress))
+ if r.URL.Path == "/settings" {
+ p.configLock.Lock()
+ defer p.configLock.Unlock()
+
+ bytes, err := json.Marshal(p.config.settingsJson)
+ if err == nil {
+ fmt.Fprint(w, string(bytes))
+ } else {
+ p.API.LogError(fmt.Sprintf("Unable to json Marshal settings %s", err.Error()))
+ }
+
+ return
+ }
if r.URL.Path == "/status" {
p.doorLock.Lock()
defer p.doorLock.Unlock()
@@ -480,6 +504,36 @@
}
}
+ newConfig.doorNames = make([]string, 0, 4)
+
+ split = strings.Split(newConfig.DoorNames, "|")
+ for _, un := range split {
+ trimmed := strings.Trim(un, ", \t\n")
+ if trimmed != "" {
+ newConfig.doorNames = append(newConfig.doorNames, trimmed)
+ }
+ }
+
+ min := func(a uint8, b uint8) uint8 {
+ if a < b {
+ return a
+ }
+ return b
+ }
+
+ doorsJson := make(map[string]string)
+ for i := uint8(0); i < min(uint8(len(newConfig.doorNames)), newConfig.numDoors); i++ {
+ doorsJson[fmt.Sprintf("%d", i + 1)] = newConfig.doorNames[i]
+ }
+
+ newConfig.settingsJson = map[string]interface{} {
+ "info_icon": newConfig.InfoIcon,
+ "unknown_icon": newConfig.UnknownIcon,
+ "open_icon": newConfig.OpenIcon,
+ "closed_icon": newConfig.ClosedIcon,
+ "doors": doorsJson,
+ }
+
p.config = newConfig
p.configUpdates++
diff --git a/mattermost/webapp/dist/main.js b/mattermost/webapp/dist/main.js
index 4cca171..adb6cdf 100644
--- a/mattermost/webapp/dist/main.js
+++ b/mattermost/webapp/dist/main.js
@@ -106,9 +106,24 @@
this.state = {
doors: {}
};
+ this.settings = {};
}
componentDidMount() {
+ this.getSettings();
+ }
+
+ async getSettings() {
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/settings";
+ var res = await fetch(url);
+ this.settings = await res.json();
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.getSettings.bind(this), 5000);
+ return;
+ }
+
Registry.registerWebSocketEventHandler("custom_com.mattermost.bathroom_updated", this.updateDoors.bind(this));
this.updateDoors();
}
@@ -118,22 +133,40 @@
}
async updateDoors(msg) {
- var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
- var res = await fetch(url);
- var json = await res.json();
- this.setState({
- "doors": json
- });
+ //var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/status";
+ var res = await fetch(url);
+ var json = await res.json();
+ this.setState({
+ "doors": json
+ });
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.updateDoors.bind(this), 3000);
+ }
}
render() {
if (!this.state.doors) return;
var columns = 6;
var keys = Object.keys(this.state.doors).sort();
- var width = Math.floor(100 / columns) + "%";
+ var width = Math.floor(100 / (columns + 1)) + "%";
var widthPx = "23px";
var elems = [];
var row = [];
+ var rows = 0;
+
+ var IconImg = props => _react.default.createElement("img", {
+ src: props.src,
+ width: "100%",
+ style: {
+ "padding": "2px"
+ },
+ title: props.title
+ });
+
+ var totalRows = Math.floor(keys.length / columns) + 1;
for (var i = 0; i < keys.length
/*(Math.floor(keys.length / 6) + 1) * 6*/
@@ -141,31 +174,16 @@
var img = null;
if (i < keys.length) {
- var door = this.state.doors[keys[i]];
- var imgFile = null;
+ var key = keys[i];
+ var door = this.state.doors[key];
+ var imgFile = this.settings[door + "_icon"];
- switch (door) {
- default:
- case "unknown":
- imgFile = "/static/emoji/2753.png";
- break;
-
- case "open":
- imgFile = "/static/emoji/1f6bd.png";
- break;
-
- case "closed":
- imgFile = "/static/emoji/26d4-fe0f.png";
- break;
+ if (imgFile) {
+ img = _react.default.createElement(IconImg, {
+ src: imgFile,
+ title: this.settings.doors[key]
+ }); //img =
}
-
- img = _react.default.createElement("img", {
- src: imgFile,
- width: "100%",
- style: {
- "padding": "2px"
- }
- });
}
row.push(_react.default.createElement("td", {
@@ -173,8 +191,23 @@
}, img));
if (i % columns == columns - 1 || i == keys.length - 1) {
- elems.push(_react.default.createElement(_react.default.Fragment, null, [...row]));
+ if (rows == 0) {
+ row.unshift( // |
+ _react.default.createElement("td", {
+ rowspan: totalRows,
+ width: widthPx,
+ style: {
+ "color": this.props.theme.sidebarText,
+ "padding-right": "5px"
+ }
+ }, _react.default.createElement(IconImg, {
+ src: this.settings.info_icon
+ }), ":"));
+ }
+
+ elems.push(_react.default.createElement("tr", null, [...row]));
row.length = 0;
+ rows++;
}
}
@@ -188,7 +221,8 @@
}, _react.default.createElement("table", {
style: {
"margin-left": "auto",
- "margin-right": "auto"
+ "margin-right": "auto",
+ "border": "1px solid " + this.props.theme.sidebarText
}
}, elems))
);
diff --git a/mattermost/webapp/dist/main.js.map b/mattermost/webapp/dist/main.js.map
index 26114e4..99ecff9 100644
--- a/mattermost/webapp/dist/main.js.map
+++ b/mattermost/webapp/dist/main.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.jsx","webpack:///external \"React\""],"names":["BathroomComponent","React","Component","constructor","props","state","doors","componentDidMount","Registry","registerWebSocketEventHandler","updateDoors","bind","componentWillUnmount","unregisterWebSocketEventHandler","msg","url","Store","getState","entities","general","config","SiteURL","res","fetch","json","setState","render","columns","keys","Object","sort","width","Math","floor","widthPx","elems","row","i","length","img","door","imgFile","push","BathroomMonitorPlugin","initialize","registry","store","registerLeftSidebarHeaderComponent","window","registerPlugin"],"mappings":"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","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import React from 'react';\n\nclass BathroomComponent extends React.Component\n{\n constructor(props)\n {\n super(props);\n this.state = {doors:{}};\n }\n componentDidMount()\n {\n Registry.registerWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\", this.updateDoors.bind(this));\n this.updateDoors();\n }\n componentWillUnmount()\n {\n Registry.unregisterWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\");\n }\n async updateDoors(msg)\n {\n var url = Store.getState().entities.general.config.SiteURL + \"/plugins/com.mattermost.bathroom/status\";\n var res = await fetch(url);\n var json = await res.json();\n this.setState({\"doors\":json});\n }\n render()\n {\n if (!this.state.doors) return;\n var columns = 6;\n var keys = Object.keys(this.state.doors).sort();\n var width = (Math.floor(100 / columns)) + \"%\";\n var widthPx = \"23px\";\n var elems = [];\n var row = [];\n for (var i = 0; i < keys.length /*(Math.floor(keys.length / 6) + 1) * 6*/; i++)\n {\n var img = null;\n if (i < keys.length)\n {\n var door = this.state.doors[keys[i]];\n var imgFile = null;\n switch (door)\n {\n default:\n case \"unknown\":\n imgFile = \"/static/emoji/2753.png\";\n break;\n case \"open\":\n imgFile = \"/static/emoji/1f6bd.png\";\n break;\n case \"closed\":\n imgFile = \"/static/emoji/26d4-fe0f.png\";\n break;\n }\n img =
\n }\n row.push({img} | );\n if (i % columns == columns - 1 || i == keys.length - 1)\n {\n elems.push({[...row]});\n row.length = 0;\n }\n }\n return (\n //\n \n );\n }\n}\n\nvar Registry = null;\nvar Store = null;\n\nclass BathroomMonitorPlugin\n{\n initialize(registry, store)\n {\n Registry = registry;\n Store = store;\n registry.registerLeftSidebarHeaderComponent(BathroomComponent);\n }\n}\n\nwindow.registerPlugin('com.mattermost.bathroom', new BathroomMonitorPlugin());\n","module.exports = React;"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.jsx","webpack:///external \"React\""],"names":["BathroomComponent","React","Component","constructor","props","state","doors","settings","componentDidMount","getSettings","url","window","location","origin","res","fetch","json","e","console","log","setTimeout","bind","Registry","registerWebSocketEventHandler","updateDoors","componentWillUnmount","unregisterWebSocketEventHandler","msg","setState","render","columns","keys","Object","sort","width","Math","floor","widthPx","elems","row","rows","IconImg","src","title","totalRows","length","i","img","key","door","imgFile","push","unshift","theme","sidebarText","info_icon","Store","BathroomMonitorPlugin","initialize","registry","store","registerLeftSidebarHeaderComponent","registerPlugin"],"mappings":"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","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import React from 'react';\n\nclass BathroomComponent extends React.Component\n{\n constructor(props)\n {\n super(props);\n this.state = {doors:{}};\n this.settings = {};\n }\n componentDidMount()\n {\n this.getSettings();\n }\n async getSettings()\n {\n try\n {\n\n var url = window.location.origin + \"/plugins/com.mattermost.bathroom/settings\";\n var res = await fetch(url);\n this.settings = await res.json();\n }\n catch (e)\n {\n console.log(e);\n setTimeout(this.getSettings.bind(this), 5000);\n return;\n }\n\n Registry.registerWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\", this.updateDoors.bind(this));\n this.updateDoors();\n }\n componentWillUnmount()\n {\n Registry.unregisterWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\");\n }\n async updateDoors(msg)\n {\n //var url = Store.getState().entities.general.config.SiteURL + \"/plugins/com.mattermost.bathroom/status\";\n try\n {\n var url = window.location.origin + \"/plugins/com.mattermost.bathroom/status\";\n var res = await fetch(url);\n var json = await res.json();\n this.setState({\"doors\":json});\n }\n catch (e)\n {\n console.log(e);\n setTimeout(this.updateDoors.bind(this), 3000);\n }\n }\n render()\n {\n if (!this.state.doors) return;\n var columns = 6;\n var keys = Object.keys(this.state.doors).sort();\n var width = Math.floor(100 / (columns + 1)) + \"%\";\n var widthPx = \"23px\";\n var elems = [];\n var row = [];\n var rows = 0;\n var IconImg = props =>
;\n var totalRows = Math.floor(keys.length / columns) + 1;\n for (var i = 0; i < keys.length /*(Math.floor(keys.length / 6) + 1) * 6*/; i++)\n {\n var img = null;\n if (i < keys.length)\n {\n var key = keys[i];\n var door = this.state.doors[key];\n var imgFile = this.settings[door + \"_icon\"];\n if (imgFile)\n {\n img = ;\n //img =
\n }\n }\n row.push({img} | );\n if (i % columns == columns - 1 || i == keys.length - 1)\n {\n if (rows == 0)\n {\n row.unshift(\n // | \n : | \n );\n }\n elems.push({[...row]}
);\n row.length = 0;\n rows++;\n }\n }\n return (\n //\n \n );\n }\n}\n\nvar Registry = null;\nvar Store = null;\n\nclass BathroomMonitorPlugin\n{\n initialize(registry, store)\n {\n Registry = registry;\n Store = store;\n registry.registerLeftSidebarHeaderComponent(BathroomComponent);\n }\n}\n\nwindow.registerPlugin('com.mattermost.bathroom', new BathroomMonitorPlugin());\n","module.exports = React;"],"sourceRoot":""}
\ No newline at end of file
diff --git a/mattermost/bathroom.tar.gz b/mattermost/bathroom.tar.gz
index 246e3c9..0b66090 100644
--- a/mattermost/bathroom.tar.gz
+++ b/mattermost/bathroom.tar.gz
Binary files differ
diff --git a/mattermost/package.sh b/mattermost/package.sh
old mode 100644
new mode 100755
diff --git a/mattermost/plugin.json b/mattermost/plugin.json
index ba3a186..872bd8c 100644
--- a/mattermost/plugin.json
+++ b/mattermost/plugin.json
@@ -10,8 +10,13 @@
"settings_schema": {
"settings": [
{"key":"NumDoors", "display_name":"Number of Door Sensors", "type":"text", "default":"1", "help_text":"How many Pis"},
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/plugin_templ.json b/mattermost/plugin_templ.json
index 634b204..fad5981 100644
--- a/mattermost/plugin_templ.json
+++ b/mattermost/plugin_templ.json
@@ -13,9 +13,14 @@
#ifdef fsnotify
{"key":"WatchPath", "display_name":"Pi status folder", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
#else
- {"key":"KeyPath", "display_name":"", "type":"text", "default":"./", "help_text":"Path to watch for doorX files updated from PHP"},
+ {"key":"KeyPath", "display_name":"Public key path", "type":"text", "default":"./", "help_text":"Path for public keys to server Pi requests"},
#endif
- {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"}
+ {"key":"AdminUsers", "display_name":"Plugin admin users", "type":"text", "default":"", "help_text":"Space- or comma-separated list of users to notify with plugin debug message"},
+ {"key":"DoorNames", "display_name":"Door names", "type":"text", "default":"", "help_text":"|-separated list of names of the office doors"},
+ {"key":"InfoIcon", "display_name":"Info icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display at the left before all the door icons"},
+ {"key":"UnknownIcon", "display_name":"Unknown icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors without their status set yet"},
+ {"key":"OpenIcon", "display_name":"Open icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are open"},
+ {"key":"ClosedIcon", "display_name":"Closed icon url", "type":"text", "default":"", "help_text":"(Relative) URL of the icon to display for doors that are closed"}
]
}
}
diff --git a/mattermost/server/bathroom-linux-amd64 b/mattermost/server/bathroom-linux-amd64
index c478ac9..673a918 100755
--- a/mattermost/server/bathroom-linux-amd64
+++ b/mattermost/server/bathroom-linux-amd64
Binary files differ
diff --git a/mattermost/server/bathroom.go b/mattermost/server/bathroom.go
index b3512ab..7637e45 100644
--- a/mattermost/server/bathroom.go
+++ b/mattermost/server/bathroom.go
@@ -28,6 +28,7 @@
"crypto/sha1"
"path"
"encoding/base64"
+ _ "math"
)
const DO_LOGGING = false
@@ -77,6 +78,16 @@
adminUsers []string
KeyPath string
+
+ DoorNames string
+ doorNames []string
+
+ InfoIcon string
+ UnknownIcon string
+ OpenIcon string
+ ClosedIcon string
+
+ settingsJson map[string]interface{}
}
type BathroomMonitorPlugin struct {
@@ -218,6 +229,19 @@
func (p *BathroomMonitorPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
p.log(fmt.Sprintf("Requested path: %s %s", r.URL.Path, c.IpAddress))
+ if r.URL.Path == "/settings" {
+ p.configLock.Lock()
+ defer p.configLock.Unlock()
+
+ bytes, err := json.Marshal(p.config.settingsJson)
+ if err == nil {
+ fmt.Fprint(w, string(bytes))
+ } else {
+ p.API.LogError(fmt.Sprintf("Unable to json Marshal settings %s", err.Error()))
+ }
+
+ return
+ }
if r.URL.Path == "/status" {
p.doorLock.Lock()
defer p.doorLock.Unlock()
@@ -480,6 +504,36 @@
}
}
+ newConfig.doorNames = make([]string, 0, 4)
+
+ split = strings.Split(newConfig.DoorNames, "|")
+ for _, un := range split {
+ trimmed := strings.Trim(un, ", \t\n")
+ if trimmed != "" {
+ newConfig.doorNames = append(newConfig.doorNames, trimmed)
+ }
+ }
+
+ min := func(a uint8, b uint8) uint8 {
+ if a < b {
+ return a
+ }
+ return b
+ }
+
+ doorsJson := make(map[string]string)
+ for i := uint8(0); i < min(uint8(len(newConfig.doorNames)), newConfig.numDoors); i++ {
+ doorsJson[fmt.Sprintf("%d", i + 1)] = newConfig.doorNames[i]
+ }
+
+ newConfig.settingsJson = map[string]interface{} {
+ "info_icon": newConfig.InfoIcon,
+ "unknown_icon": newConfig.UnknownIcon,
+ "open_icon": newConfig.OpenIcon,
+ "closed_icon": newConfig.ClosedIcon,
+ "doors": doorsJson,
+ }
+
p.config = newConfig
p.configUpdates++
diff --git a/mattermost/webapp/dist/main.js b/mattermost/webapp/dist/main.js
index 4cca171..adb6cdf 100644
--- a/mattermost/webapp/dist/main.js
+++ b/mattermost/webapp/dist/main.js
@@ -106,9 +106,24 @@
this.state = {
doors: {}
};
+ this.settings = {};
}
componentDidMount() {
+ this.getSettings();
+ }
+
+ async getSettings() {
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/settings";
+ var res = await fetch(url);
+ this.settings = await res.json();
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.getSettings.bind(this), 5000);
+ return;
+ }
+
Registry.registerWebSocketEventHandler("custom_com.mattermost.bathroom_updated", this.updateDoors.bind(this));
this.updateDoors();
}
@@ -118,22 +133,40 @@
}
async updateDoors(msg) {
- var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
- var res = await fetch(url);
- var json = await res.json();
- this.setState({
- "doors": json
- });
+ //var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
+ try {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/status";
+ var res = await fetch(url);
+ var json = await res.json();
+ this.setState({
+ "doors": json
+ });
+ } catch (e) {
+ console.log(e);
+ setTimeout(this.updateDoors.bind(this), 3000);
+ }
}
render() {
if (!this.state.doors) return;
var columns = 6;
var keys = Object.keys(this.state.doors).sort();
- var width = Math.floor(100 / columns) + "%";
+ var width = Math.floor(100 / (columns + 1)) + "%";
var widthPx = "23px";
var elems = [];
var row = [];
+ var rows = 0;
+
+ var IconImg = props => _react.default.createElement("img", {
+ src: props.src,
+ width: "100%",
+ style: {
+ "padding": "2px"
+ },
+ title: props.title
+ });
+
+ var totalRows = Math.floor(keys.length / columns) + 1;
for (var i = 0; i < keys.length
/*(Math.floor(keys.length / 6) + 1) * 6*/
@@ -141,31 +174,16 @@
var img = null;
if (i < keys.length) {
- var door = this.state.doors[keys[i]];
- var imgFile = null;
+ var key = keys[i];
+ var door = this.state.doors[key];
+ var imgFile = this.settings[door + "_icon"];
- switch (door) {
- default:
- case "unknown":
- imgFile = "/static/emoji/2753.png";
- break;
-
- case "open":
- imgFile = "/static/emoji/1f6bd.png";
- break;
-
- case "closed":
- imgFile = "/static/emoji/26d4-fe0f.png";
- break;
+ if (imgFile) {
+ img = _react.default.createElement(IconImg, {
+ src: imgFile,
+ title: this.settings.doors[key]
+ }); //img =
}
-
- img = _react.default.createElement("img", {
- src: imgFile,
- width: "100%",
- style: {
- "padding": "2px"
- }
- });
}
row.push(_react.default.createElement("td", {
@@ -173,8 +191,23 @@
}, img));
if (i % columns == columns - 1 || i == keys.length - 1) {
- elems.push(_react.default.createElement(_react.default.Fragment, null, [...row]));
+ if (rows == 0) {
+ row.unshift( // |
+ _react.default.createElement("td", {
+ rowspan: totalRows,
+ width: widthPx,
+ style: {
+ "color": this.props.theme.sidebarText,
+ "padding-right": "5px"
+ }
+ }, _react.default.createElement(IconImg, {
+ src: this.settings.info_icon
+ }), ":"));
+ }
+
+ elems.push(_react.default.createElement("tr", null, [...row]));
row.length = 0;
+ rows++;
}
}
@@ -188,7 +221,8 @@
}, _react.default.createElement("table", {
style: {
"margin-left": "auto",
- "margin-right": "auto"
+ "margin-right": "auto",
+ "border": "1px solid " + this.props.theme.sidebarText
}
}, elems))
);
diff --git a/mattermost/webapp/dist/main.js.map b/mattermost/webapp/dist/main.js.map
index 26114e4..99ecff9 100644
--- a/mattermost/webapp/dist/main.js.map
+++ b/mattermost/webapp/dist/main.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.jsx","webpack:///external \"React\""],"names":["BathroomComponent","React","Component","constructor","props","state","doors","componentDidMount","Registry","registerWebSocketEventHandler","updateDoors","bind","componentWillUnmount","unregisterWebSocketEventHandler","msg","url","Store","getState","entities","general","config","SiteURL","res","fetch","json","setState","render","columns","keys","Object","sort","width","Math","floor","widthPx","elems","row","i","length","img","door","imgFile","push","BathroomMonitorPlugin","initialize","registry","store","registerLeftSidebarHeaderComponent","window","registerPlugin"],"mappings":"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","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import React from 'react';\n\nclass BathroomComponent extends React.Component\n{\n constructor(props)\n {\n super(props);\n this.state = {doors:{}};\n }\n componentDidMount()\n {\n Registry.registerWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\", this.updateDoors.bind(this));\n this.updateDoors();\n }\n componentWillUnmount()\n {\n Registry.unregisterWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\");\n }\n async updateDoors(msg)\n {\n var url = Store.getState().entities.general.config.SiteURL + \"/plugins/com.mattermost.bathroom/status\";\n var res = await fetch(url);\n var json = await res.json();\n this.setState({\"doors\":json});\n }\n render()\n {\n if (!this.state.doors) return;\n var columns = 6;\n var keys = Object.keys(this.state.doors).sort();\n var width = (Math.floor(100 / columns)) + \"%\";\n var widthPx = \"23px\";\n var elems = [];\n var row = [];\n for (var i = 0; i < keys.length /*(Math.floor(keys.length / 6) + 1) * 6*/; i++)\n {\n var img = null;\n if (i < keys.length)\n {\n var door = this.state.doors[keys[i]];\n var imgFile = null;\n switch (door)\n {\n default:\n case \"unknown\":\n imgFile = \"/static/emoji/2753.png\";\n break;\n case \"open\":\n imgFile = \"/static/emoji/1f6bd.png\";\n break;\n case \"closed\":\n imgFile = \"/static/emoji/26d4-fe0f.png\";\n break;\n }\n img =
\n }\n row.push({img} | );\n if (i % columns == columns - 1 || i == keys.length - 1)\n {\n elems.push({[...row]});\n row.length = 0;\n }\n }\n return (\n //\n \n );\n }\n}\n\nvar Registry = null;\nvar Store = null;\n\nclass BathroomMonitorPlugin\n{\n initialize(registry, store)\n {\n Registry = registry;\n Store = store;\n registry.registerLeftSidebarHeaderComponent(BathroomComponent);\n }\n}\n\nwindow.registerPlugin('com.mattermost.bathroom', new BathroomMonitorPlugin());\n","module.exports = React;"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.jsx","webpack:///external \"React\""],"names":["BathroomComponent","React","Component","constructor","props","state","doors","settings","componentDidMount","getSettings","url","window","location","origin","res","fetch","json","e","console","log","setTimeout","bind","Registry","registerWebSocketEventHandler","updateDoors","componentWillUnmount","unregisterWebSocketEventHandler","msg","setState","render","columns","keys","Object","sort","width","Math","floor","widthPx","elems","row","rows","IconImg","src","title","totalRows","length","i","img","key","door","imgFile","push","unshift","theme","sidebarText","info_icon","Store","BathroomMonitorPlugin","initialize","registry","store","registerLeftSidebarHeaderComponent","registerPlugin"],"mappings":"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","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import React from 'react';\n\nclass BathroomComponent extends React.Component\n{\n constructor(props)\n {\n super(props);\n this.state = {doors:{}};\n this.settings = {};\n }\n componentDidMount()\n {\n this.getSettings();\n }\n async getSettings()\n {\n try\n {\n\n var url = window.location.origin + \"/plugins/com.mattermost.bathroom/settings\";\n var res = await fetch(url);\n this.settings = await res.json();\n }\n catch (e)\n {\n console.log(e);\n setTimeout(this.getSettings.bind(this), 5000);\n return;\n }\n\n Registry.registerWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\", this.updateDoors.bind(this));\n this.updateDoors();\n }\n componentWillUnmount()\n {\n Registry.unregisterWebSocketEventHandler(\"custom_com.mattermost.bathroom_updated\");\n }\n async updateDoors(msg)\n {\n //var url = Store.getState().entities.general.config.SiteURL + \"/plugins/com.mattermost.bathroom/status\";\n try\n {\n var url = window.location.origin + \"/plugins/com.mattermost.bathroom/status\";\n var res = await fetch(url);\n var json = await res.json();\n this.setState({\"doors\":json});\n }\n catch (e)\n {\n console.log(e);\n setTimeout(this.updateDoors.bind(this), 3000);\n }\n }\n render()\n {\n if (!this.state.doors) return;\n var columns = 6;\n var keys = Object.keys(this.state.doors).sort();\n var width = Math.floor(100 / (columns + 1)) + \"%\";\n var widthPx = \"23px\";\n var elems = [];\n var row = [];\n var rows = 0;\n var IconImg = props =>
;\n var totalRows = Math.floor(keys.length / columns) + 1;\n for (var i = 0; i < keys.length /*(Math.floor(keys.length / 6) + 1) * 6*/; i++)\n {\n var img = null;\n if (i < keys.length)\n {\n var key = keys[i];\n var door = this.state.doors[key];\n var imgFile = this.settings[door + \"_icon\"];\n if (imgFile)\n {\n img = ;\n //img =
\n }\n }\n row.push({img} | );\n if (i % columns == columns - 1 || i == keys.length - 1)\n {\n if (rows == 0)\n {\n row.unshift(\n // | \n : | \n );\n }\n elems.push({[...row]}
);\n row.length = 0;\n rows++;\n }\n }\n return (\n //\n \n );\n }\n}\n\nvar Registry = null;\nvar Store = null;\n\nclass BathroomMonitorPlugin\n{\n initialize(registry, store)\n {\n Registry = registry;\n Store = store;\n registry.registerLeftSidebarHeaderComponent(BathroomComponent);\n }\n}\n\nwindow.registerPlugin('com.mattermost.bathroom', new BathroomMonitorPlugin());\n","module.exports = React;"],"sourceRoot":""}
\ No newline at end of file
diff --git a/mattermost/webapp/src/index.jsx b/mattermost/webapp/src/index.jsx
index 0868e33..17189b2 100644
--- a/mattermost/webapp/src/index.jsx
+++ b/mattermost/webapp/src/index.jsx
@@ -6,9 +6,28 @@
{
super(props);
this.state = {doors:{}};
+ this.settings = {};
}
componentDidMount()
{
+ this.getSettings();
+ }
+ async getSettings()
+ {
+ try
+ {
+
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/settings";
+ var res = await fetch(url);
+ this.settings = await res.json();
+ }
+ catch (e)
+ {
+ console.log(e);
+ setTimeout(this.getSettings.bind(this), 5000);
+ return;
+ }
+
Registry.registerWebSocketEventHandler("custom_com.mattermost.bathroom_updated", this.updateDoors.bind(this));
this.updateDoors();
}
@@ -18,53 +37,65 @@
}
async updateDoors(msg)
{
- var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
- var res = await fetch(url);
- var json = await res.json();
- this.setState({"doors":json});
+ //var url = Store.getState().entities.general.config.SiteURL + "/plugins/com.mattermost.bathroom/status";
+ try
+ {
+ var url = window.location.origin + "/plugins/com.mattermost.bathroom/status";
+ var res = await fetch(url);
+ var json = await res.json();
+ this.setState({"doors":json});
+ }
+ catch (e)
+ {
+ console.log(e);
+ setTimeout(this.updateDoors.bind(this), 3000);
+ }
}
render()
{
if (!this.state.doors) return;
var columns = 6;
var keys = Object.keys(this.state.doors).sort();
- var width = (Math.floor(100 / columns)) + "%";
+ var width = Math.floor(100 / (columns + 1)) + "%";
var widthPx = "23px";
var elems = [];
var row = [];
+ var rows = 0;
+ var IconImg = props =>
;
+ var totalRows = Math.floor(keys.length / columns) + 1;
for (var i = 0; i < keys.length /*(Math.floor(keys.length / 6) + 1) * 6*/; i++)
{
var img = null;
if (i < keys.length)
{
- var door = this.state.doors[keys[i]];
- var imgFile = null;
- switch (door)
+ var key = keys[i];
+ var door = this.state.doors[key];
+ var imgFile = this.settings[door + "_icon"];
+ if (imgFile)
{
- default:
- case "unknown":
- imgFile = "/static/emoji/2753.png";
- break;
- case "open":
- imgFile = "/static/emoji/1f6bd.png";
- break;
- case "closed":
- imgFile = "/static/emoji/26d4-fe0f.png";
- break;
+ img = ;
+ //img =
}
- img =
}
row.push({img} | );
if (i % columns == columns - 1 || i == keys.length - 1)
{
- elems.push({[...row]});
+ if (rows == 0)
+ {
+ row.unshift(
+ // |
+ : |
+ );
+ }
+ elems.push({[...row]}
);
row.length = 0;
+ rows++;
}
}
return (
//