Difference between revisions of "MediaWiki:Gadget-fix-schedule-times.js"

From WikiConference North America
Jump to navigation Jump to search
(remove the word "started" for most of them)
(fix up for soft ending times)
Line 17: Line 17:
 
var TIME_REGEX = /(\d\d):(\d\d)( - (\d\d):(\d\d)|\+)/;
 
var TIME_REGEX = /(\d\d):(\d\d)( - (\d\d):(\d\d)|\+)/;
   
function formatRelativeTime( minutesUntilStart, minutesUntilEnd ) {
+
function formatRelativeTime( minutesUntilStart, minutesUntilEnd, countdownDuringEvent ) {
 
if ( minutesUntilStart > /* one day */ 1440 ) {
 
if ( minutesUntilStart > /* one day */ 1440 ) {
return "In " + ( minutesUntilStart / 1440 ).toFixed( 0 ) + " days";
+
return "in " + ( minutesUntilStart / 1440 ).toFixed( 0 ) + " days";
 
} else if ( minutesUntilStart > /* 3 hours */ 180 ) {
 
} else if ( minutesUntilStart > /* 3 hours */ 180 ) {
return "In " + ( minutesUntilStart / 60 ).toFixed( 0 ) + " hours";
+
return "in " + ( minutesUntilStart / 60 ).toFixed( 0 ) + " hours";
 
} else if ( minutesUntilStart > 120 ) {
 
} else if ( minutesUntilStart > 120 ) {
return "In 2 hours and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + " minutes";
+
return "in 2 hours and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + " minutes";
 
} else if ( minutesUntilStart > 60 ) {
 
} else if ( minutesUntilStart > 60 ) {
return "In an hour and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + " minutes";
+
return "in an hour and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + " minutes";
 
} else if ( minutesUntilStart > 1 ) {
 
} else if ( minutesUntilStart > 1 ) {
return "In " + minutesUntilStart.toFixed( 0 ) + " minutes";
+
return "in " + minutesUntilStart.toFixed( 0 ) + " minutes";
 
} else if ( minutesUntilStart > 0 ) {
 
} else if ( minutesUntilStart > 0 ) {
return "In less than a minute";
+
return "in less than a minute";
 
} else if ( minutesUntilStart > -1 ) {
 
} else if ( minutesUntilStart > -1 ) {
return "Started just now";
+
return "started just now";
 
} else if ( minutesUntilStart > -5 ) {
 
} else if ( minutesUntilStart > -5 ) {
return "Started " + ( -minutesUntilStart ).toFixed( 0 ) + " minutes ago";
+
return "started " + ( -minutesUntilStart ).toFixed( 0 ) + " minutes ago";
 
} else if ( minutesUntilEnd > 1 ) {
 
} else if ( minutesUntilEnd > 1 ) {
  +
if ( countdownDuringEvent ) {
return "Ends in " + minutesUntilEnd.toFixed( 0 ) + " minutes";
+
return "ends in " + minutesUntilEnd.toFixed( 0 ) + " minutes";
  +
} else {
  +
if ( minutesUntilStart > -60 ) {
  +
return "started " + ( -minutesUntilStart ).toFixed( 0 ) + " minutes ago";
  +
} else {
  +
return "started " + ( -minutesUntilStart / 60 ).toFixed( 0 ) + " hours ago";
  +
}
  +
}
 
} else if ( minutesUntilEnd > 0 ) {
 
} else if ( minutesUntilEnd > 0 ) {
return "Ends in one minute";
+
return "ends in one minute";
 
} else if ( minutesUntilEnd > -1 ) {
 
} else if ( minutesUntilEnd > -1 ) {
return "Ended just now";
+
return "ended just now";
 
} else if ( minutesUntilEnd > -60 ) {
 
} else if ( minutesUntilEnd > -60 ) {
return "Ended " + ( -minutesUntilEnd ).toFixed( 0 ) + " minutes ago";
+
return "ended " + ( -minutesUntilEnd ).toFixed( 0 ) + " minutes ago";
 
} else if ( minutesUntilEnd > -1440 ) {
 
} else if ( minutesUntilEnd > -1440 ) {
return "Ended " + ( -minutesUntilEnd / 60 ).toFixed( 0 ) + " hours ago";
+
return "ended " + ( -minutesUntilEnd / 60 ).toFixed( 0 ) + " hours ago";
 
} else {
 
} else {
return "Ended " + ( -minutesUntilEnd / 1440 ).toFixed( 0 ) + " days ago";
+
return "ended " + ( -minutesUntilEnd / 1440 ).toFixed( 0 ) + " days ago";
 
}
 
}
 
}
 
}
Line 57: Line 65:
 
var dayHeadingText = dayHeading.find( ".mw-headline" ).text();
 
var dayHeadingText = dayHeading.find( ".mw-headline" ).text();
 
var baseDateUnix = Math.floor( CONFERENCE_DAYS[dayHeadingText] / 1000 );
 
var baseDateUnix = Math.floor( CONFERENCE_DAYS[dayHeadingText] / 1000 );
  +
var isSoftEndingTime = !!originalTimeMatch[4]; // if there's no group-4 match, no ending time was specified
   
 
// First, get the actual timestamps
 
// First, get the actual timestamps
 
var startTimeUnix = baseDateUnix + parseInt( originalTimeMatch[1], 10 ) * 3600 +
 
var startTimeUnix = baseDateUnix + parseInt( originalTimeMatch[1], 10 ) * 3600 +
 
parseInt( originalTimeMatch[2], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS;
 
parseInt( originalTimeMatch[2], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS;
var endTimeUnix = originalTimeMatch[4] ? ( baseDateUnix + parseInt( originalTimeMatch[4], 10 ) * 3600 +
+
var endTimeUnix = isSoftEndingTime ? ( baseDateUnix + parseInt( originalTimeMatch[4], 10 ) * 3600 +
parseInt( originalTimeMatch[5], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS ) : startTimeUnix;
+
parseInt( originalTimeMatch[5], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS ) : ( startTimeUnix + 3600 * 5 );
   
 
// Now, get some text like "Starts in 10 minutes".
 
// Now, get some text like "Starts in 10 minutes".
Line 68: Line 77:
 
var relativeTimeFormatted = formatRelativeTime(
 
var relativeTimeFormatted = formatRelativeTime(
 
( startTimeUnix - nowUnix ) / 60,
 
( startTimeUnix - nowUnix ) / 60,
( endTimeUnix - nowUnix ) / 60
+
( endTimeUnix - nowUnix ) / 60,
  +
/* countdownDuringEvent */ !isSoftEndingTime,
 
);
 
);
return formatTime( startTimeUnix ) + " - " + ( ( startTimeUnix === endTimeUnix ) ? "" : formatTime( endTimeUnix ) ) + "<br />(" + relativeTimeFormatted + ")";
+
return formatTime( startTimeUnix ) + ( isSoftEndingTime ? "+" : ( " - " + formatTime( endTimeUnix ) ) ) + "<br />(" + relativeTimeFormatted + ")";
 
}
 
}
   

Revision as of 03:26, 7 October 2021

// vim: ts=4 sw=4 et ai si
$.when(
    $.ready
).then( function () {
// quit immediately if dontFixSchedule is in the URL after the ?
if(window.location.search.indexOf("dontFixSchedule")>=0)return;

    // Configuration
    var CONFERENCE_DAYS = {
        "Friday, October 8": Date.UTC( 2021, /* month index, not month number! */ 9, 8 ),
        "Saturday, October 9": Date.UTC( 2021, 9, 9 ),
        "Sunday, October 10": Date.UTC( 2021, 9, 10 )
    };
    var WRITTEN_SCHEDULE_OFFSET_SECONDS = -4 * 3600; // written schedule for WCNA 2021 is Eastern Time which is UTC-4

    // Other constants
    var TIME_REGEX = /(\d\d):(\d\d)( - (\d\d):(\d\d)|\+)/;

    function formatRelativeTime( minutesUntilStart, minutesUntilEnd, countdownDuringEvent ) {
        if ( minutesUntilStart > /* one day */ 1440 ) {
            return "in " + ( minutesUntilStart / 1440 ).toFixed( 0 ) + "&nbsp;days";
        } else if ( minutesUntilStart > /* 3 hours */ 180 ) {
            return "in " + ( minutesUntilStart / 60 ).toFixed( 0 ) + "&nbsp;hours";
        } else if ( minutesUntilStart > 120 ) {
            return "in 2&nbsp;hours and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + "&nbsp;minutes";
        } else if ( minutesUntilStart > 60 ) {
            return "in an&nbsp;hour and " + ( minutesUntilStart % 60 ).toFixed( 0 ) + "&nbsp;minutes";
        } else if ( minutesUntilStart > 1 ) {
            return "in " + minutesUntilStart.toFixed( 0 ) + "&nbsp;minutes";
        } else if ( minutesUntilStart > 0 ) {
            return "in less than a minute";
        } else if ( minutesUntilStart > -1 ) {
            return "started just&nbsp;now";
        } else if ( minutesUntilStart > -5 ) {
            return "started " + ( -minutesUntilStart ).toFixed( 0 ) + "&nbsp;minutes&nbsp;ago";
        } else if ( minutesUntilEnd > 1 ) {
            if ( countdownDuringEvent ) {
                return "ends in " + minutesUntilEnd.toFixed( 0 ) + "&nbsp;minutes";
            } else {
                if ( minutesUntilStart > -60 ) {
                    return "started " + ( -minutesUntilStart ).toFixed( 0 ) + "&nbsp;minutes&nbsp;ago";
                } else {
                    return "started " + ( -minutesUntilStart / 60 ).toFixed( 0 ) + "&nbsp;hours&nbsp;ago";
                }
            }
        } else if ( minutesUntilEnd > 0 ) {
            return "ends in one&nbsp;minute";
        } else if ( minutesUntilEnd > -1 ) {
            return "ended just&nbsp;now";
        } else if ( minutesUntilEnd > -60 ) {
            return "ended " + ( -minutesUntilEnd ).toFixed( 0 ) + "&nbsp;minutes ago";
        } else if ( minutesUntilEnd > -1440 ) {
            return "ended " + ( -minutesUntilEnd / 60 ).toFixed( 0 ) + "&nbsp;hours ago";
        } else {
            return "ended " + ( -minutesUntilEnd / 1440 ).toFixed( 0 ) + "&nbsp;days ago";
        }
    }

    function formatTime( unixTimestamp ) {
        return new Date( unixTimestamp * 1000 ).toLocaleTimeString().replace( /(\d\d?:\d\d):00/, "$1" ).replace( / /g, "&nbsp;" );
    }

    function makeHtml( originalTimeMatch, tableCell ) {
        var dayHeading = $( tableCell ).closest( "table" ).prev().prev(); // skip icon key
        var dayHeadingText = dayHeading.find( ".mw-headline" ).text();
        var baseDateUnix = Math.floor( CONFERENCE_DAYS[dayHeadingText] / 1000 );
        var isSoftEndingTime = !!originalTimeMatch[4]; // if there's no group-4 match, no ending time was specified

        // First, get the actual timestamps
        var startTimeUnix = baseDateUnix + parseInt( originalTimeMatch[1], 10 ) * 3600 +
                parseInt( originalTimeMatch[2], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS;
        var endTimeUnix = isSoftEndingTime ? ( baseDateUnix + parseInt( originalTimeMatch[4], 10 ) * 3600 +
                parseInt( originalTimeMatch[5], 10 ) * 60 - WRITTEN_SCHEDULE_OFFSET_SECONDS ) : ( startTimeUnix + 3600 * 5 );

        // Now, get some text like "Starts in 10 minutes".
        var nowUnix = Math.floor( new Date().getTime() / 1000 );
        var relativeTimeFormatted = formatRelativeTime(
            ( startTimeUnix - nowUnix ) / 60,
            ( endTimeUnix - nowUnix ) / 60,
            /* countdownDuringEvent */ !isSoftEndingTime,
        );
        return formatTime( startTimeUnix ) + ( isSoftEndingTime ? "+" : ( " - " + formatTime( endTimeUnix ) ) ) + "<br />(" + relativeTimeFormatted + ")";
    }

    $( "small" ).each( function () {
        if ( this.textContent === "(US Eastern Time)" ) {
try{
            $( this ).text( "In " + Intl.DateTimeFormat().resolvedOptions().timeZone.replace( /_/g, " " ) + " time" );
}catch(e){
console.error(e);
$(this).text("In your local timezone (hover to see Eastern U.S. time)");
        }
        }
    } );

    $( "td" ).each( function () {
        var match = TIME_REGEX.exec( this.textContent );
        if ( match ) {
            this.innerHTML = this.innerHTML.replace( match[0], "<span class='fixed' title='"+match[0]+" Eastern Time' data-original='" + match[0] + "'>" + match[0] + "</span>" );
        }
    } );

    function go() {
        $( "span.fixed" ).each( function () {
            $( this ).html( makeHtml( TIME_REGEX.exec( this.dataset.original ), this.parentNode ) );
        } );
    }

    go();
    window.setInterval( go, 60 * 1000 );
} );