]> code.delx.au - comingnext/blobdiff - comingNext/index.html
Work around for bug by fixing the current Date rather than amending calendar dates
[comingnext] / comingNext / index.html
index 7a867235ee33683bb982e9ef151c2a84bf533c7d..1d45580d63d013d6d51dc91e79dfecb5c112fdc2 100644 (file)
 .calendar6 { background-color:#9fdf57 }\r
 </style>\r
 \r
-<script type="text/javascript" src="localizedTextStrings.js" charset="utf-8" />\r
-\r
-<script>\r
+<script type="text/javascript" src="localizedTextStrings.js" charset="utf-8"></script>\r
+<script type="text/javascript" src="../debug.js" charset="utf-8"></script>\r
+<script type="text/javascript">\r
 // valid types for the config object are 'Int', 'Bool', 'String', 'Enum', 'UID', 'Array'\r
 var config = {\r
+       fontsize: { Type: 'Enum', Default: 'auto', Value: 'auto', ValidValues: ['auto', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'],},\r
+       eventsPerWidget: { Type: 'Int', Default: 4, Value: 4,},\r
        monthRange: { Type: 'Int', Default: 2, Value: 2,},\r
+       maxNumberOfEventsOnFullscreen: { Type: 'Int', Default: 30, Value: 30,},\r
        includeTodos: { Type: 'Bool', Default: true, Value: true,},\r
        useBackgroundImage: { Type: 'Bool', Default: true, Value: true,},\r
        backgroundImageLocation: { Type: 'Enum', Default: 'internal', Value: 'internal', ValidValues: ['internal', 'external']},\r
        showCombinedDateTime: { Type: 'Bool', Default: false, Value: false,},\r
        showLocation: { Type: 'Bool', Default: true, Value: true,},\r
+       showIcons: { Type: 'Bool', Default: true, Value: true,},\r
        showTodayAsText: { Type: 'Bool', Default: true, Value: true,},\r
        todayText: { Type: 'String', Default: getLocalizedText('settings.default.todayText'), Value: getLocalizedText('settings.default.todayText'),},\r
        tomorrowText: { Type: 'String', Default: getLocalizedText('settings.default.tomorrowText'), Value: getLocalizedText('settings.default.tomorrowText'),},\r
@@ -49,7 +53,6 @@ var config = {
        weekDayLength: { Type: 'Int', Default: 2, Value: 2,},\r
        updateDataInterval: { Type: 'Int', Default: 5, Value: 5,},\r
        calendarApp: { Type: 'UID', Default: 0x10005901, Value: 0x10005901,},\r
-       eventsPerWidget: { Type: 'Int', Default: 4, Value: 4,},\r
        showNothingText: { Type: 'Bool', Default: true, Value: true,},\r
        nothingText: { Type: 'String', Default: getLocalizedText('settings.default.nothingText'), Value: getLocalizedText('settings.default.nothingText'),},\r
        enableDaylightSaving: { Type: 'Bool', Default: true, Value: true,},\r
@@ -58,6 +61,7 @@ var config = {
        showCalendarIndicator: { Type: 'Bool', Default: true, Value: true,},\r
        excludedCalendars: { Type: 'Array', Default: [], Value: [],},\r
        enableLogging: { Type: 'Bool', Default: false, Value: false,},\r
+       anonymizeLogging: { Type: 'Bool', Default: false, Value: false,},\r
        cssStyle_background: { Type: 'String', Default: 'color:#ffffff; background-color:#000000', Value: 'color:#ffffff; background-color:#000000',},\r
        cssStyle_backgroundFullscreen: { Type: 'String', Default: 'color:#ffffff; background-color:#000000', Value: 'color:#ffffff; background-color:#000000',},\r
        cssStyle_weekDay: { Type: 'String', Default: '', Value: '',},\r
@@ -67,7 +71,7 @@ var config = {
        cssStyle_time: { Type: 'String', Default: '', Value: '',},\r
        cssStyle_now: { Type: 'String', Default: 'color:#ff00ff', Value: 'color:#ff00ff',},\r
        cssStyle_description: { Type: 'String', Default: '', Value: '',},\r
-       cssStyle_icon: { Type: 'String', Default: 'width:15px; height:15px', Value: 'width:15px; height:15px',},\r
+       cssStyle_icon: { Type: 'String', Default: '', Value: '',},\r
        cssStyle_overdue: { Type: 'String', Default: 'color:#ffff00', Value: 'color:#ffff00',},\r
        cssStyle_calendar1: { Type: 'String', Default: 'background-color:#0757cf', Value: 'background-color:#0757cf',},\r
        cssStyle_calendar2: { Type: 'String', Default: 'background-color:#579f37', Value: 'background-color:#579f37',},\r
@@ -82,15 +86,27 @@ var config = {
 //-------------------------------------------------------\r
 // Nothing of interest from here on...\r
 //-------------------------------------------------------\r
+\r
+function fixDate(d) {\r
+       if (d.getTimezoneOffset() < -12*60) {\r
+               d = new Date((new Date(d.getTime()-24*3600*1000)).toLocaleString());\r
+       }\r
+       return d\r
+}\r
+\r
+function newDate() {\r
+       return fixDate(new Date());\r
+}\r
+\r
 var panelNum = 0; // use 1 for second panel\r
-var version = "1.34";\r
+var version = "1.37";\r
 var versionURL = "http://comingnext.sourceforge.net/version.xml";\r
 var calendarService = null;\r
 var cacheEntriesHtml = [];\r
 var months_translated = [];\r
 var weekdays_translated = [];\r
 var orientation = '';\r
-var now = new Date();\r
+var now = newDate();\r
 var mode = 0; // 0 = homescreen, 1 = fullscreen, 2 = settings, 3 = about, 4 = check for update\r
 var reqV = null; \r
 var settingsCalEntryId = null;\r
@@ -108,6 +124,7 @@ var entryLists = null; // stores all fetched calendar entries until data is refr
 var statupSuccessful = false; // indicates if everything started up wihtout errors. If we detect an error after that, it might just be a temporary problem e.g. by a backup process.\r
 var use12hoursTimeFormat = false; // defines how time should be formated: 19:00 or 07:00 pm\r
 var timeFormatSeparator = ":"; // format time 19:00 or 19.00 depending on system setting\r
+var defaultFontSize = null; // default browser font size will be set by init\r
 \r
 // vars for daylight saving time\r
 var summertime = false; // true, if current date is in summer, false if in winter\r
@@ -250,7 +267,7 @@ function collectLocales()
                }\r
        }\r
        for (weekday = 0; weekday < 7; weekday++) {\r
-               var startDate = new Date(2000, 0, 2 + weekday); // date that we know for sure is a sunday\r
+               var startDate = new Date(2000, 0, 2 + weekday, 12); // date that we know for sure is a sunday\r
 \r
                var item = new Object();\r
                item.Type = "DayEvent";\r
@@ -375,11 +392,16 @@ function collectLocales()
        }\r
 }\r
 \r
+function stringEndsWith(str, suffix)\r
+{\r
+       return str.indexOf(suffix, str.length - suffix.length) !== -1;\r
+}\r
+\r
 // detects the system's current time format by parsing a native calendar timestamp (this is the only reliable formating across all devices and firmwares)\r
 function detectTimeFormat(localeTimeString)\r
 {\r
        localeTimeString = localeTimeString.toLowerCase();\r
-       use12hoursTimeFormat = localeTimeString.indexOf("am") != -1 || localeTimeString.indexOf("pm") != -1 ? true : false;\r
+       use12hoursTimeFormat = stringEndsWith(localeTimeString, "am") || stringEndsWith(localeTimeString, "pm");\r
        timeFormatSeparator = localeTimeString.indexOf(":") != -1 ? ":" : ".";\r
 }\r
 \r
@@ -527,7 +549,7 @@ function parseDate(dateString)
 \r
 function getWeekdayLocalized(date) {\r
        var localizedString = date.toLocaleDateString();\r
-       if (localizedString.match(/\d\d.\d\d.\d\d(\d\d)?/)) {\r
+       if (localizedString.indexOf(",") == -1) {\r
                return weekdays_translated[date.getDay()];\r
        } else\r
                return localizedString.split(',')[0];\r
@@ -658,7 +680,7 @@ function updateData()
                lastReloadTime = null; // force calendar data reload on this update\r
        }\r
 \r
-       now = new Date();\r
+       now = newDate();\r
        \r
        // only reload calendar data every 6 hours, visual updates occure more often\r
        if (!lastReloadTime || now.getTime() - lastReloadTime.getTime() > reloadInterval) {\r
@@ -716,7 +738,7 @@ function updateData()
                        } else {\r
                                entryLists = [meetingList];\r
                        }\r
-                       lastReloadTime = new Date();\r
+                       lastReloadTime = newDate();\r
                } catch(e) {\r
                        error('loading Calendar items list:' + e + ', line ' + e.line);\r
                        return;\r
@@ -728,24 +750,19 @@ function updateData()
                var counter = 0;\r
                var entryDate = '';\r
                var dateArr = [];\r
-               var fontsize = 'normal';\r
-               var lineheight = 'normal';\r
+               var fontsize = getDefaultFontSize()[1] + 'px';\r
+               var lineheight = fontsize;\r
                if (mode == 0) {\r
-                       fontsize = parseInt(72 / config['eventsPerWidget'].Value) + 'px';\r
-                       lineheight = parseInt(82 / config['eventsPerWidget'].Value) + 'px';\r
-                       \r
-                       if (config['eventsPerWidget'].Value == 3) {\r
-                               changeCssClass('.icon', 'width:20px; height:20px');\r
-                       }\r
-                       else if (config['eventsPerWidget'].Value == 5) {\r
-                               changeCssClass('.icon', 'width:10px; height:10px');\r
-                       }\r
-                       else if (config['eventsPerWidget'].Value == 6) {\r
-                               changeCssClass('.icon', 'width:8px; height:8px');\r
+                       if (config['fontsize'].Value == config['fontsize'].ValidValues[0]) {\r
+                               fontsize = parseInt(72 / config['eventsPerWidget'].Value) + 'px';\r
+                               lineheight = parseInt(72 / config['eventsPerWidget'].Value) + 'px';\r
                        }\r
                }\r
-               else\r
-                       changeCssClass('.icon', config['cssStyle_icon'].Value);\r
+               if (config['fontsize'].Value != config['fontsize'].ValidValues[0]) {\r
+                       fontsize = config['fontsize'].Value + 'px';\r
+                       lineheight = fontsize;\r
+               }\r
+               changeCssClass('.icon', config['cssStyle_icon'].Value + '; width:' + fontsize + '; height:' + fontsize + ';');\r
                var entriesHtml = '<table style="font-size:' + fontsize + '; line-height:' + lineheight + ';">';\r
                if (mode == 0)\r
                        entriesHtml = '<table width="307" height="82"><tr><td>' + entriesHtml; // this is needed to center the actual content vertically\r
@@ -754,7 +771,7 @@ function updateData()
                if (mode == 0)\r
                        max = (panelNum + 1) * config['eventsPerWidget'].Value;\r
                else\r
-                       max = 30; // we can display a lot more events in fullscreen mode\r
+                       max = config["maxNumberOfEventsOnFullscreen"].Value; // we can display a lot more events in fullscreen mode\r
 \r
                if (config['enableLogging'].Value) {\r
                        var listinfo = "";\r
@@ -890,9 +907,12 @@ function updateData()
                                // generate html output\r
                                entriesHtml += '<tr>';\r
                                if (config['showCalendarIndicator'].Value && calendarList.length - config['excludedCalendars'].Value.length > 1) {\r
-                                       entriesHtml += '<td><span class="calendar' + calendarColors[entry.CalendarName] + '">&nbsp;</span></td>';\r
+                                       entriesHtml += '<td><div class="calendar' + calendarColors[entry.CalendarName] + '" style="height:' + (lineheight.split("px")[0] - 1) + 'px; width:4px;"></div></td>';\r
                                }\r
-                               entriesHtml += '<td><img class="icon" src="' + entry.Type + '.png" /></td>';\r
+                               if (config['showIcons'].Value)\r
+                                       entriesHtml += '<td><img class="icon" align="top" src="' + entry.Type + '.png" /></td>';\r
+                               else\r
+                                       entriesHtml += '<td style="padding:0px;"></td>';\r
                                if(date == null) {\r
                                        // some languages have very strange locale date formats, can't parse all those. Also some todos don't have dates at all.\r
                                        entriesHtml += '<td colspan="4"><span class="date">' + entryDate + '</span> ';\r
@@ -936,6 +956,7 @@ function updateData()
                        var text = config['nothingText'].Value.replace(/%d/, config['monthRange'].Value);\r
                        entriesHtml = '<div style="width:295px; height:75px; text-align:center; line-height:75px; overflow:visible;">' + text + '</div>';\r
                }\r
+               log("output: " + entriesHtml);\r
                if (cacheEntriesHtml != entriesHtml) {\r
                        if (mode == 0)\r
                                document.getElementById('calendarList').innerHTML = entriesHtml;\r
@@ -944,7 +965,7 @@ function updateData()
                        cacheEntriesHtml = entriesHtml;\r
                }\r
                \r
-               lastUpdateTime = new Date();\r
+               lastUpdateTime = newDate();\r
        } catch(e) {\r
                error('displaying list:' + e + ', line ' + e.line);\r
                return;\r
@@ -954,16 +975,21 @@ function updateData()
 // called by handleOnShow() and onResize events\r
 function updateScreen()\r
 {\r
-       log('updateScreen()');\r
+       log('updateScreen(): mode=' + mode + ', window.innerHeight=' + window.innerHeight);\r
 \r
        // check if opening fullscreen\r
-       if( window.innerHeight > 91 && mode == 0) {\r
+\r
+       // Note: according to Nokia's documentation, an innerHeight of >91 is an indicator for fullscreen view. \r
+       // However a bug in E6's firmware causes different window widths and heights (disabled compatibility scaling). \r
+       // So far, values of 104 and 115 for window.innerHeight were reported, we use a safty margin here and check \r
+       // for 150 instead.\r
+       if( window.innerHeight > 150 && mode == 0) {\r
                mode = 1;\r
                cacheEntriesHtml = '';\r
                document.getElementById('body').style.backgroundImage = "";\r
                showFullscreen();\r
        }\r
-       else if (window.innerHeight <= 91 && mode != 0) {\r
+       else if (window.innerHeight <= 150 && mode != 0) {\r
                mode = 0;\r
                cacheEntriesHtml = '';\r
                showHomescreen();\r
@@ -979,7 +1005,7 @@ function handleOnShow()
 {\r
        updateScreen();\r
 \r
-       var time = new Date();\r
+       var time = newDate();\r
        if (time.getTime() - lastUpdateTime.getTime() > config['updateDataInterval'].Value * 60 * 1000) {\r
                log('updateScreen(): force updateData() because last update was too long ago (' + (time.getTime() - lastUpdateTime.getTime()) / 1000 + 's)');\r
                clearUpdateTimer();\r
@@ -1159,8 +1185,12 @@ function showSettings()
                        settingsHtml += '<table><tr><td>' + getLocalizedText('settings.name.' + key) + '<br /><input class="textInput" name="settings.' + key + '" type="text" value="0x' + config[key].Value.toString(16) + '" /></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '<hr />';\r
                else if (config[key].Type == 'Enum') {\r
                        settingsHtml += '<table><tr><td>' + getLocalizedText('settings.name.' + key) + '<br /><select name="settings.' + key + '" size="1">';\r
-                       for(var i = 0; i < config[key].ValidValues.length; i++)\r
-                               settingsHtml += '<option value="' + config[key].ValidValues[i] + '"' + (config[key].Value == config[key].ValidValues[i] ? ' selected="selected"' : '') + '>' + getLocalizedText('settings.validValues.' + key + '.' + config[key].ValidValues[i]) + '</option>';\r
+                       for(var i = 0; i < config[key].ValidValues.length; i++) {\r
+                               var text = getLocalizedText('settings.validValues.' + key + '.' + config[key].ValidValues[i]);\r
+                               if (text.indexOf('ERROR') == 0)\r
+                                       text = config[key].ValidValues[i];\r
+                               settingsHtml += '<option value="' + config[key].ValidValues[i] + '"' + (config[key].Value == config[key].ValidValues[i] ? ' selected="selected"' : '') + '>' + text + '</option>';\r
+                       }\r
                        settingsHtml += '</select></div></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '<hr />';\r
                }\r
                else if (config[key].Type == 'Array') {\r
@@ -1294,7 +1324,7 @@ function loadSettings()
                                        log('Warning: unknown or invalid setting: ' + stringlist[i]);\r
                                        continue;\r
                                }\r
-                               log('stringlist: ' + key + '=\'' + value + '\'');\r
+                               log('stringlist[' + i + ']: ' + key + '=\'' + value + '\'');\r
                                if (config[key].Type == 'Int') {\r
                                        config[key].Value = Number(value);\r
                                        if (isNaN(config[key].Value))\r
@@ -1386,7 +1416,7 @@ function printHintBox(text)
 {\r
        uniqueId++;\r
        return '<td width="1%" align="right" onclick="javascript:toggleVisibility(\'info' + uniqueId + '\')">' + getLocalizedText('settings.help') + '</td></tr></table>'+\r
-              '<div class="settingsInfo" id="info' + uniqueId + '">' + text + '</div>';\r
+              '<div class="settingsInfo" id="info' + uniqueId + '" style="display:none">' + text + '</div>';\r
 }\r
 \r
 function showAbout()\r
@@ -1516,7 +1546,6 @@ function checkForUpdate()
        reqV.onreadystatechange = checkForUpdateCallback;\r
        document.getElementById("updateDiv").innerHTML = getLocalizedText("update.checking");\r
        reqV.open("GET", versionURL, true);\r
-       reqV.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" ); // disable caching\r
        reqV.send(null);\r
 }\r
 \r
@@ -1603,6 +1632,12 @@ function listToArray(list, calendarName)
                if (!itemCopy['CalendarName']) {\r
                        itemCopy['CalendarName'] = calendarName;\r
                }\r
+               if (config['anonymizeLogging'].Value && config['enableLogging'].Value) {\r
+                       if (itemCopy['Summary'])\r
+                               itemCopy['Summary'] = getHashForString(itemCopy['Summary']);\r
+                       if (itemCopy['Location'])\r
+                               itemCopy['Location'] = getHashForString(itemCopy['Location']);\r
+               }\r
                array.push(itemCopy);\r
                txt += array[array.length - 1].Summary + ", ";\r
        }\r
@@ -1722,12 +1757,38 @@ function log(message)
        }\r
 }\r
 \r
+function getDefaultFontSize()\r
+{\r
+       if (defaultFontSize == null) {\r
+               var pa = document.body;\r
+               var who = document.createElement('div');\r
+               who.className = 'defaultEm';\r
+               who.appendChild(document.createTextNode('M'));\r
+               pa.appendChild(who);\r
+               var fs = [who.offsetWidth, who.offsetHeight];\r
+               pa.removeChild(who);\r
+               defaultFontSize = fs;\r
+       }\r
+       return defaultFontSize;\r
+}\r
+\r
+function getHashForString(string)\r
+{\r
+       // cheap hashing, loosly based on Java's String.hashCode()\r
+       for (var hash = 0, i = 0; i < string.length; i++)\r
+               hash = (hash << 5) - hash + string.charCodeAt(i);\r
+       hash = hash & hash; // Convert to 32bit integer\r
+       if (hash < 0)\r
+               hash = -hash;\r
+       return hash.toString(16).toUpperCase();\r
+}\r
+\r
 </script>\r
 \r
 <style type="text/css">\r
 a { color:#aaccff }\r
 table { margin:0px; padding:0px; border-spacing:0px; border-collapse: collapse; }\r
-td { padding:0px 5px 0px 0px; white-space:nowrap; overflow:hidden; margin:0px; }\r
+td { padding:0px 5px 0px 0px; white-space:nowrap; overflow:visible; margin:0px; }\r
 hr { color:#ffffff; background-color:#ffffff; height:1px; text-align:left; border-style:none; }\r
 .settingsInfo { display:none; font-style:italic; }\r
 .title { font-weight:bold; font-size:14pt; }\r
@@ -1738,6 +1799,7 @@ hr { color:#ffffff; background-color:#ffffff; height:1px; text-align:left; borde
 #name { text-align:center; }\r
 #appicon { display: block; margin-left: auto; margin-right: auto; margin-top: 10px; }\r
 #smallappicon { width:22px; height:22px; margin-right:10px; float:left; }\r
+.defaultEm { font-size:1em; position:absolute; line-height:1; padding:0; visibility:hidden; } \r
 </style>\r
 \r
 </head>\r
@@ -1766,11 +1828,15 @@ hr { color:#ffffff; background-color:#ffffff; height:1px; text-align:left; borde
        <p>Contributions:</p>\r
                <p class="credits">Paul Moore (bug fixes, new features and code cleanup)</p>\r
                <p class="credits">Manfred Hanselmann (DST support)</p>\r
-               <p class="credits">Christophe Milsent (translation support & french translation)</p>\r
-               <p class="credits">Flavio Nathan (portuguese-brazilian translation)</p>\r
-               <p class="credits">Tokeda (russian translation)</p>\r
-               <p class="credits">Marcella Ferrari (italian translation)</p>\r
-               <p class="credits">Venos (italian translation)</p>\r
+               <p class="credits">Christophe Milsent (translation support & French translation)</p>\r
+               <p class="credits">Flavio Nathan (Portuguese-Brazilian translation)</p>\r
+               <p class="credits">Tokeda (Russian translation)</p>\r
+               <p class="credits">Marcella Ferrari (Italian translation)</p>\r
+               <p class="credits">Venos (Italian translation)</p>\r
+               <p class="credits">Francisco Rodero (Catalan translation)</p>\r
+               <p class="credits">zbigzbig20 (Polish translation)</p>\r
+               <p class="credits">Streamkeskus (Finnish translation)</p>\r
+               <p class="credits">renek (Czech translation)</p>\r
        <p>This software is open source and licensed under the GPLv3.</p>\r
        <p>Visit <a onclick="widget.openURL('http://comingnext.sf.net/'); return false;" href="http://comingnext.sf.net/">comingnext.sf.net</a> for free updates.</p>\r
        <hr />\r