MagicMirror² v2.5.0 is available! For more information about this release, check out this topic.

Need some styling help here!



  • Allright lads. Here is my custom.css and a snippet from a module i need some help with.

    The module is a timetable for the busses in my area basically.
    I am only trying to a small thing, wich is that i want the color of the entire line to change color as the time closes in on when the bus is supposed to leave. Say at 15 minutes its the neat blue color i already have, but under 10 changes to yellow. And at 5 minutes turns red.

    The second bit im struggeling with is the actual width of the entire table. I cant seem to modify it much. I can shrink it quite a bit, but im unable to get it to be the same width as the rest of my modules on that side of the mirror, wich for me is quite annoying.

    Hope someone can help me out here.
    Screenshots and code added below.

    /* Magic Mirror
     * Module: Ruter
     *
     * By Cato Antonsen (https://github.com/CatoAntonsen)
     * MIT Licensed.
     */
    
    Module.register("MMM-Skyss",{
    
        // Default module config.
        defaults: {
            timeFormat: null,              // This is set automatically based on global config
            showHeader: false,             // Set this to true to show header above the journeys (default is false)
            showPlatform: false,           // Set this to true to get the names of the platforms (default is false)
            showStopName: false,           // Show the name of the stop (you have to configure 'name' for each stop)
            maxItems: 5,                   // Number of journeys to display (default is 5)
            humanizeTimeTreshold: 15,      // If time to next journey is below this value, it will be displayed as "x minutes" instead of time (default is 15 minutes)
            serviceReloadInterval: 30000,  // Refresh rate in MS for how often we call Skyss' web service. NB! Don't set it too low! (default is 30 seconds)
            animationSpeed: 0,             // How fast the animation changes when updating mirror (default is 0 second)
            fade: true,                    // Set this to true to fade list from light to dark. (default is true)
            fadePoint: 0.25,               // Start on 1/4th of the list.
            useRealtime: true              // Whether to use realtime data from Skyss
        },
    
        getStyles: function () {
            return ["skyss.css"];
        },
    
        getScripts: function() {
            return [];
        },
    
        getTranslations: function() {
            return {
                en: "translations/en.json",
                nb: "translations/nb.json"
            }
        },
    
        start: function() {
            console.log(this.translate("STARTINGMODULE") + ": " + this.name);
    
            this.journeys = [];
            this.previousJourneys = [];
            var self = this;
    
             // Set locale and time format based on global config
            if (config.timeFormat === 24) {
                this.config.timeFormat = "HH:mm";
            } else {
                this.config.timeFormat = "h:mm A";
            }
    
            // Just do an initial poll. Otherwise we have to wait for the serviceReloadInterval
            self.startPolling();
    
            setInterval(function() {
                self.startPolling();
            }, this.config.serviceReloadInterval);
        },
    
        getDom: function() {
            if (this.journeys.length > 0) {
    
                var table = document.createElement("table");
                table.className = "ruter small";
    
                if (this.config.showHeader) {
                    table.appendChild(this.getTableHeaderRow());
                }
    
                for(var i = 0; i < this.journeys.length; i++) {
    
                    var journey = this.journeys[i];
                    var tr = this.getTableRow(journey);
    
                    // Create fade effect. = startingPoint) {
                            var currentStep = i - startingPoint;
                            tr.style.opacity = 1 - (1 / steps * currentStep);
                        }
                    }
    
                    table.appendChild(tr);
                }
    
                return table;
            } else {
                var wrapper = document.createElement("div");
                wrapper.innerHTML = this.translate("LOADING");
                wrapper.className = "small dimmed";
                return wrapper;
            }
    
        },
    
        startPolling: function() {
            var self = this;
    
            var promise = new Promise((resolv) => {
                this.getStopInfo(this.config.stops, function(err, result) {
                    resolv(result);
                });
            });
    
            promise.then(function(promiseResults) {
                if (promiseResults.length > 0) {
                    var allJourneys = [];
                    for(var i=0; i < promiseResults.length; i++) {
                        allJourneys = allJourneys.concat(promiseResults[i])
                    }
    
                    allJourneys.sort(function(a,b) {
                        var dateA = new Date(a.time.Timestamp);
                        var dateB = new Date(b.time.Timestamp);
                        return dateA - dateB;
                    });
    
                    self.journeys = allJourneys.slice(0, self.config.maxItems);
    
                    self.updateDom();
                }
            });
        },
    
        getStopInfo: function(stopItems, callback) {
            var self = this;
    
            var HttpClient = function() {
                this.get = function(requestUrl, requestCallback) {
                    // var httpRequest = new XMLHttpRequest();
                    // httpRequest.onreadystatechange = function() {
                    //     if (httpRequest.readyState == 4 && httpRequest.status == 200){
                    //         requestCallback(httpRequest.responseText);
                    //     }
                    // };
    
                    // httpRequest.open("GET", requestUrl, true);
                    // httpRequest.setRequestHeader("Authorization", "");
                    // httpRequest.send(null);
                    self.requests.push(requestCallback);
                    self.sendSocketNotification("getstop", requestUrl);
                }
            }
        
            //DisplayTime contains realtime-information. Formatted as "x min"(remaining time), or "HH:mm"
            var processSkyssDisplaytime = function(displayTime) {
                var realTime;
                var regexInMinutes = new RegExp('([0-9]+) min');
                var regexLocalTimeStamp = new RegExp('[0-9]{2}\:[0-9]{2}');
            
                //Time format is "x min"
                if (regexInMinutes.test(displayTime)) {
                    inMinutes = parseInt(displayTime.match(regexInMinutes)[1]);
                
                    // Adding 1 gives same result as skyss app -.-
                    realTime = moment().add(inMinutes+1, 'minutes');
                
                //Time format is "HH:mm". 
                } else if (regexLocalTimeStamp.test(displayTime)) {
                    realTime = moment(displayTime, "HH:mm");
                
                    //Time is next day
                    if (realTime.isBefore(moment())) {
                    	realTime.add(1, 'day');
                    }
                }
                return realTime;
            };
            
    
            // var shouldAddPlatform = function(platform, platformFilter) {
            //     if (platformFilter == null || platformFilter.length == 0) { return true; } // If we don't add any interesting platformFilter, then we asume we'll show all
            //     for(var i=0; i < platformFilter.length; i++) {
            //         if (platformFilter[i] === platform) { return true; }
            //     }
    
            //     return false;
            // };
    
            // var departureUrl = function() {
            //     var dateParam = "";
            //     if (stopItem.timeToThere) {
            //         var min = stopItem.timeToThere;
            //         var timeAhead = moment(moment.now()).add(min, "minute").format().substring(0, 16);
            //         console.log("Looking for journeys " + min + " minutes ahead in time.");
            //         dateParam = "?datetime=" + timeAhead;
            //     } else {
            //         console.log("Looking for current journeys");
            //     }
    
            //     return "http://reisapi.ruter.no/StopVisit/GetDepartures/" + stopItem.stopId + dateParam;
            // };
    
            var stopUrl = function() {
                return "/public/departures?Hours=12&StopIdentifiers=" + stopItems.map(stopItem => stopItem.stopId).join();
            };
    
            var client = new HttpClient();
    
            client.get(stopUrl(), function(stopResponse) {
                var departure = JSON.parse(stopResponse);
                var times = departure.PassingTimes;
    
                var allStopItems = [];
    
                for(var j = 0; j < times.length; j++) {
                    var journey = times[j];
                    var stop = departure.Stops[journey.StopIdentifier];
                    var timestamp;
                    
                    var realtimeStamp = processSkyssDisplaytime(journey.DisplayTime);
                    if ( self.config.useRealtime && moment.isMoment(realtimeStamp) ) {
                        timestamp = realtimeStamp.toISOString();
                    } else {
                        timestamp = journey.AimedTime;
                    }
                    
                    allStopItems.push({
                        stopId: journey.StopIdentifier,
                        stopName: stop.PlaceDescription,
                        lineName: journey.RoutePublicIdentifier,
                        destinationName: journey.TripDestination,
                        service: stop.ServiceModes[0],
                        time: {
                            Timestamp: timestamp,
                            Status: journey.Status,
                        },
                        platform: journey.Platform
                    });
                }
                callback(null, allStopItems);
            })
        },
    
        getTableHeaderRow: function() {
            var thLine = document.createElement("th");
            thLine.className = "";
            thLine.appendChild(document.createTextNode(this.translate("LINEHEADER")));
    
            var thDestination = document.createElement("th");
            thDestination.className = "";
            thDestination.appendChild(document.createTextNode(this.translate("DESTINATIONHEADER")));
    
            var thPlatform = document.createElement("th");
            thPlatform.className = "";
            thPlatform.appendChild(document.createTextNode(this.translate("PLATFORMHEADER")));
    
            var thStopName = document.createElement("th");
            thStopName.className = "";
            thStopName.appendChild(document.createTextNode(this.translate("STOPNAMEHEADER")));
    
            var thTime = document.createElement("th");
            thTime.className = "time";
            thTime.appendChild(document.createTextNode(this.translate("TIMEHEADER")));
    
            var thead = document.createElement("thead");
            thead.addClass = "xsmall dimmed";
            thead.appendChild(document.createElement("th"));
            thead.appendChild(thLine);
            thead.appendChild(thDestination);
            if (this.config.showStopName) { thead.appendChild(thStopName); }
            if (this.config.showPlatform) { thead.appendChild(thPlatform); }
            thead.appendChild(thTime);
    
            return thead;
        },
    
        getTableRow: function(journey) {
            var tdIcon = document.createElement("td");
            var imageFA;
            switch (journey.service) {
            case "Bus":
            case "Express":
            case "Airport bus":
                imageFA = "bus";
                break;
            case "Light rail":
                imageFA = "subway";
                break;
            case "Ferry":
            case "Boat":
                imageFA = "ship";
                break;
            case "Train":
                imageFA = "train";
                break;
            default:
                imageFA = "rocket";
                break;
            }
            tdIcon.className = "fa fa-"+imageFA;
    
            var tdLine = document.createElement("td");
            tdLine.className = "line";
            var txtLine = document.createTextNode(journey.lineName);
            tdLine.appendChild(txtLine);
    
            var tdDestination = document.createElement("td");
            tdDestination.className = "destination bright";
            tdDestination.appendChild(document.createTextNode(journey.destinationName));
    
            if (this.config.showPlatform) {
                var tdPlatform = document.createElement("td");
                tdPlatform.className = "platform";
                tdPlatform.appendChild(document.createTextNode(journey.platform));
            }
    
            if (this.config.showStopName) {
                var tdStopName = document.createElement("td");
                tdStopName.className = "light";
                tdStopName.appendChild(document.createTextNode(journey.stopName));
            }
    
            var tdTime = document.createElement("td");
            if (journey.time.Status != "Schedule") {
                tdTime.className = "time light sanntid";
            } else {
                tdTime.className = "time light";
            }
            tdTime.appendChild(document.createTextNode(this.formatTime(journey.time.Timestamp)));
    
            var tr = document.createElement("tr");
            tr.appendChild(tdIcon);
            tr.appendChild(tdLine);
            tr.appendChild(tdDestination);
            if (this.config.showStopName) { tr.appendChild(tdStopName); }
            if (this.config.showPlatform) { tr.appendChild(tdPlatform); }
            tr.appendChild(tdTime);
    
            return tr;
        },
    
        formatTime: function(t) {
            var now = new Date();
            var tti = new Date(t);
            var diff = tti - now;
            var min = Math.floor(diff/60000);
    
            if (min == 0) {
                return this.translate("NOW");
            } else if (min == 1) {
                return this.translate("1MIN");
            } else if (min < this.config.humanizeTimeTreshold) {
                return min + " " + this.translate("MINUTES");
            } else {
                return tti.getHours() + ":" + ("0" + tti.getMinutes()).slice(-2);
            }
        },
    
        socketNotificationReceived: function(notification, payload) {
            var self = this;
            Log.log(this.name + " recieved a socket notification: " + notification);
            if (notification == "getstop") {
                if (payload.err) {
                    throw payload.err;
                } else {
                    self.requests.shift()(payload.response);
                }
            }
        },
    
        requests: []
    });
    
    
    body {
      margin: 20px;
      position: absolute;
      height: calc(100% - 20px);
      width: calc(100% - 20px);
      background: #000;
      background-Image: url("bg.jpg");
      background-size: cover;
      color: #aaa;
      font-family: "Roboto Condensed", sans-serif;
      font-weight: 400;
      font-size: 2em;
      line-height: 1.5em;
      -webkit-font-smoothing: antialiased;
    }
    .region.fullscreen {
      position: absolute;
      top: -65px;
      left: -65px;
      right: -65px;
      bottom: -65px;
    }
    /* MMM-Hue Color changes */
    .MMM-Hue .centered {
      text-align: center;
      color: #99F;
    }
    .MMM-Hue .lights-all-on {
      color: #FF8000;
    }
    .MMM-Hue .lights-partial-on {
      color: #A46526;
    }
    .MMM-Hue .fa-home {
      color: #FF8000;
    }
    .MMM-Hue td {
      color: #99F;
    }
    /* MMM-Hue header color */
    .MMM-Hue .header {
      color: #99F;
    }
    .clock .time {
      color: #99F;
      text-transform: uppercase;
    }
    .clock .date {
      color: #99F;
      text-transform: uppercase;
    }
    .calendar_monthly table {
      width: initial;
      float: left;
    }
    .calendar_monthly td {
      text-align: left !important;
    }
    .calendar_monthly calendar-table {
      text-align: left !important;
    }
    .calendar_monthly {
      color: #99F;
      width: 350px;
    } 
    /* Highlighting today in calender */
    .square-content .today {
    	color: #2A2A2A;
    	font-weight: normal;
    	border: solid 2px #FF8000;
    	border-radius: 5px;
    	background-color: #FF8000;
    }
    /* Removes icons above max-temp, min-temp and % chance of rain */
    .region.top.right .MMM-WunderGround table th {
      display: none; 
    }
    .MMM-WunderGround .max-temp {
      color: #f66;
    }
    .MMM-WunderGround .min-temp {
      color: #0ff;
    }
    .MMM-WunderGround .weather-icon {
      color: #f93;
    }
    .MMM-WunderGround .day {
      color: #99F;
    }
    .MMM-WunderGround .large .bright {
      color: #99F;
    }
    .MMM-WunderGround table.small tr:first-child td {
      color: #99F;
    }
    .MMM-WunderGround .hourv {
      color: #99F;
    }
    /* Weather changes */
    .region.top.center .MMM-WunderGround table.small,   /* selector for ONLY current weather Thanks to Strawberry-3.141 */
    .region.top.right .MMM-WunderGround table:not(.small),   /* selector for ONLY weather forecast */
    .region.top.right .MMM-WunderGround table.small td:nth-child(6)  {
      display: none;    /* this line and line above selector for NO rain amount column */
    }
    /* Newsfeed size & color */
    .newsfeed div.light.small.dimmed {
      color: #99F;          /* color for newsfeed **source** */
      font-size: 24px;      /* size for newsfeed **source** */
    }
    /* Limit the width of the left and right columns to 350px */
    .region.right .module-content,
    .region.left .module-content {
      max-width: 350px;
    }
    /* Region left width */
    .region.left {
    width:350px;
    }
    /* Region right width */
    .region.right {
    width:350px;
    }
    /* Allows styling of row elements in tables.  You need this for the next rule */
    table.small {
      border-collapse:collapse;
    }
    /* Add an underline to table rows - also requires the rule above this one */
    table tr {
      border-bottom: solid 1px #222;
      border-bottom-color: #99F;
    }
    /* Blue colour styling for module headers */
    .module-header {
      color: #99F;
      border-bottom-color: #99F;
      font-size: 15.5px;
      font-family: "Roboto";
      text-align: center;
    }
    /* MMM-OneLiner header color & border */
    .MMM-Oneliner .header {
      color: #99F;
      border-bottom-color: #99F;
    }
    /* MMM-OneLiner text color & size & text type */
    .MMM-Oneliner .wrapper {
      color: #99F;
      font-family: 'Bubbler One', sans-serif;
      font-size: 24px;
    }
    /* MMM-NetworkScanner icon color */
    .MMM-NetworkScanner .fa-li {
      color: #FF8000;
    }
    /* MMM-NetworkScanner Name color */
    .MMM-NetworkScanner li {
      color: #99F;
    }
    /* MMM-Tools width & header color change */
    .MMM-Tools {
      width: 320px;
      color: #99F;
    }
    /* Fix for MMM-Tools - Place module anywhere */
    .Tools .status_item .container {
      margin-top:0;
    }
    /* MMM-Tools Color change right side */
    .Tools {
      color: #99F;
    }
    /* MMM-Tools Color change left side */
    .Tools .status_item .item_label {
      color: #99F;
    }
    /* MMM-Tools Transparent progress bar */
    .Tools .bar.step0 {
      background-color: #33C;
      opacity: 0.3;
    }
    .Tools .bar.step10 {
      background-color: #43B;
      opacity: 0.3;
    }
    .Tools .bar.step20 {
      background-color: #53A;
      opacity: 0.3;
    }
    .Tools .bar.step30 {
      background-color: #639;
      opacity: 0.3;
    }
    .Tools .bar.step40 {
      background-color: #738;
      opacity: 0.3;
    }
    .Tools .bar.step50 {
      background-color: #837;
      opacity: 0.3;
    }
    .Tools .bar.step60 {
      background-color: #936;
      opacity: 0.3;
    }
    .Tools .bar.step70 {
      background-color: #A35;
      opacity: 0.3;
    }
    .Tools .bar.step80 {
      background-color: #B34;
      opacity: 0.3;
    }
    .Tools .bar.step90 {
      background-color: #C33;
      opacity: 0.3;
    }
    .Tools .bar.step100 {
      background-color: #D32;
      opacity: 0.3;
    }
    
    /* MMM-NiceThings Colors */
    
    .MMM-NiceThings .morning {
    	color: #99F;
    }
    
    .MMM-NiceThings .afternoon {
    	color: #99F;
    }
    
    .MMM-NiceThings .evening {
    	color: #99F;
    }
    
    /* MMM-NowPlayingOnSpotify */
    
    .NPOS_albumCover {
    	width: 350px;
    }
    
    .MMM-NowPlayingOnSpotify {
      width: 350px;
    }
    
    /* MMM-Ruter */
    table.ruter {
      width: 0px;
      text-align: left;
    }
    
    table.ruter td, table.ruter th {
      padding: 0 6px;
      color: #99F;
      text-align: left;
    }
    
    table.ruter thead {
      border-bottom: 1px solid rgba(255, 255, 255, 0.733);
      color: #99F;
      text-align: left;
    }
    
    .ruter .time {
      padding-left: 0px;
      text-align: left;
      color: #99F;
    }
    

    0_1525469970213_Skjermbilde.JPG