diff --git a/code/dialog.js b/code/dialog.js
index 5d53d0f0..33a3beb7 100644
--- a/code/dialog.js
+++ b/code/dialog.js
@@ -1,6 +1,7 @@
// DIALOGS /////////////////////////////////////////////////////////
+// Inspired by TES III: Morrowind. Long live House Telvanni. ///////
-/* The ID of onscreen dialogs.
+/* The global ID of onscreen dialogs.
* Starts at 0.
*/
window.DIALOG_ID = 0;
@@ -9,15 +10,32 @@ window.DIALOG_ID = 0;
*/
window.DIALOGS = {};
-/* Creates a dialog and puts it onscreen. Takes one parameter: options.
+/* Creates a dialog and puts it onscreen. Takes one argument: options.
+ * Here are the most commonly used ones:
+ *
* (text|html): The text or HTML to display in the dialog. Text is auto-converted to HTML.
- * title: The dialog's title
+ * title: The dialog's title.
+ * closeCallback: A callback to run on close.
+ * modal: Whether to open a modal dialog. Implies draggable=false; dialogClass='ui-dialog-modal'.
+ * Please note that modal dialogs hijack the entire screen and should only be used in very
+ * specific cases. (If IITC is running on mobile, modal will always be true).
+ *
+ * See http://docs.jquery.com/UI/API/1.8/Dialog for a list of all the options. If you previously
+ * applied a class to your dialog after creating it with alert(), dialogClass may be particularly
+ * useful.
*/
window.dialog = function(options) {
- var id = 'dialog-' + window.DIALOG_ID++;
- var jqID = '#' + id;
+ // Override for smartphones. Preserve default behavior and create a modal dialog.
+ options = options || {};
+ if(isSmartphone()) {
+ options.modal = true;
+ }
+ var id = 'dialog-' + (options.modal ? 'modal' : window.DIALOG_ID++);
+ var jqID = '#' + id;
var html = '';
+
+ // Convert text to HTML if necessary
if(options.text) {
html = window.convertTextToTableMagic(options.text);
} else if(options.html) {
@@ -27,46 +45,102 @@ window.dialog = function(options) {
html = window.convertTextToTableMagic('');
}
+ // Modal dialogs should not be draggable
+ if(options.modal) {
+ options.dialogClass = 'ui-dialog-modal';
+ options.draggable = false;
+ }
+
+ // Create the window, appending a div to the body
$('body').append('
');
window.DIALOGS[id] = $(jqID).dialog($.extend(true, {
autoOpen: false,
modal: false,
+ draggable: true,
title: '#',
+ closeText: 'X',
buttons: {
'OK': function() {
- $(this).dialog('close');
+ $(this).dialog('close');
}
},
- close: function(event, ui) {
- console.log('window.dialog: dialog ' + $(this).dialog('option', 'title') + ' closed.');
+ create: function(event, ui) {
+ var titlebar = $(this).closest('.ui-dialog').find('.ui-dialog-titlebar');
+ var close = titlebar.find('.ui-dialog-titlebar-close');
+
+ // Title should not show up on mouseover
+ close.removeAttr('title').addClass('ui-dialog-titlebar-button');
+
+ if(!$(this).dialog('option', 'modal')) {
+ // Start out with a cloned version of the close button
+ var collapse = close.clone();
+
+ // Change it into a collapse button and set the click handler
+ collapse.addClass('ui-dialog-titlebar-button-collapse');
+ collapse.find('.ui-button-text').html('–');
+ collapse.click($.proxy(function() {
+ var collapsed = ($(this).data('collapsed') === true);
+
+ // Find the button pane and content dialog in this ui-dialog, and add or remove the 'hidden' class
+ var selector = $(this).closest('.ui-dialog').find('.ui-dialog-content,.ui-dialog-buttonpane');
+ if (collapsed) {
+ $(selector).removeClass('ui-dialog-content-hidden');
+ } else {
+ $(selector).addClass('ui-dialog-content-hidden');
+ }
+
+ // Toggle collapsed state
+ $(this).data('collapsed', !collapsed);
+ }, this));
+
+ // Put it into the titlebar
+ titlebar.prepend(collapse);
+ close.addClass('ui-dialog-titlebar-button-close');
+ }
+ },
+ close: function(event, ui) {
+ // We're closing, so log it to the console
+ console.log('window.dialog: ' + id + ' (' + $(this).dialog('option', 'title') + ') closed.');
+
+ // Run the close callback if we have one
if($(this).data('closeCallback')) {
- $(this).data('closeCallback')();
+ $.proxy($(this).data('closeCallback'), this)();
}
+ // Remove this window
$($(this).data('jqID')).remove();
delete window.DIALOGS[$(this).data('id')];
}
}, options));
+ // Set HTML and IDs
$(jqID).html(html);
- $(jqID).data('closeCallback', options.closeCallback);
$(jqID).data('id', id);
$(jqID).data('jqID', jqID);
+ // Set the callback to be executed on close
+ $(jqID).data('closeCallback', options.closeCallback);
+
+ // ui-modal includes overrides for modal dialogs
+ if (options.modal) {
+ $(jqID).parent().addClass('ui-modal');
+ }
+
+ // Run it
$(jqID).dialog('open');
+ return $(jqID);
}
-/* Deprecated. Creates a dialog with default settings.
- * Use window.dialog instead.
+/* Creates an alert dialog with default settings.
+ * If you want more configurability, use window.dialog instead.
*/
window.alert = function(text, isHTML, closeCallback) {
- var obj = {closeCallback: closeCallback};
+ var obj = {title: '', closeCallback: closeCallback};
if(isHTML) {
obj.html = text;
} else {
obj.text = text;
}
- console.log('window.alert: this function is deprecated, please use window.dialog instead');
window.dialog(obj);
}
diff --git a/code/redeeming.js b/code/redeeming.js
index 399b501f..47bb2fe8 100644
--- a/code/redeeming.js
+++ b/code/redeeming.js
@@ -92,12 +92,16 @@ window.REDEEM_HINTS = {
};
window.handleRedeemResponse = function(data, textStatus, jqXHR) {
- var passcode = this.passcode, to_dialog, to_log, buttons;
+ var passcode = this.passcode, to_dialog, to_log, dialog_title, dialog_buttons;
if(data.error) {
+ // What to display
to_dialog = '' + data.error + '
' + (window.REDEEM_ERRORS[data.error] || 'There was a problem redeeming the passcode. Try again?');
to_log = '[ERROR] ' + data.error;
- buttons = {};
+
+ // Dialog options
+ dialog_title = 'Error: ' + passcode;
+ dialog_buttons = {};
} else if(data.result) {
var encouragement = window.REDEEM_ENCOURAGEMENT[Math.floor(Math.random() * window.REDEEM_ENCOURAGEMENT.length)];
var payload = {};
@@ -199,32 +203,34 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) {
}
// Display formatted versions in a table, plaintext, and the console log
- to_dialog = '' +
+ to_dialog = '' +
results.table.map(function(a) {return '' + a + '
';}).join("\n") +
'
';
to_log = '[SUCCESS] ' + results.plain.join('/');
- buttons = {
+
+ dialog_title = 'Passcode: ' + passcode;
+ dialog_buttons = {
'PLAINTEXT' : function() {
dialog({
- title: 'Passcode: ' + passcode,
- html: '' + encouragement + '' +
- '
' + results.html.join('/') + ''
+ title: 'Rewards: ' + passcode,
+ html: '' + results.html.join('/') + ''
});
}
}
}
+ // Display it
dialog({
- title: 'Passcode: ' + passcode,
- html: to_dialog,
- buttons: buttons
+ title: dialog_title,
+ buttons: dialog_buttons,
+ html: to_dialog
});
console.log(passcode + ' => ' + to_log);
}
window.setupRedeem = function() {
$("#redeem").keypress(function(e) {
- if((e.keyCode ? e.keyCode : e.which) !== 13) return;
+ if((e.keyCode ? e.keyCode : e.which) !== 13 || !$(this).val()) return;
var data = {passcode: $(this).val()};
window.postAjax('redeemReward', data, window.handleRedeemResponse,
@@ -236,6 +242,7 @@ window.setupRedeem = function() {
extra = 'No status code was returned.';
}
dialog({
+ title: 'Request failed: ' + data.passcode,
html: 'The HTTP request failed. ' + extra
});
});
diff --git a/code/utils_misc.js b/code/utils_misc.js
index dc9c6a6f..53b61c35 100644
--- a/code/utils_misc.js
+++ b/code/utils_misc.js
@@ -27,8 +27,12 @@ window.aboutIITC = function(){
+ ' ' + attrib + '
'
+ '
'
+ ' ' + contrib + '
';
- alert(a, true, function() {$('.ui-dialog').removeClass('ui-dialog-aboutIITC');});
- $('.ui-dialog').addClass('ui-dialog-aboutIITC');
+ dialog({
+ title: 'IITC ' + v,
+ html: a,
+ dialogClass: 'ui-dialog-aboutIITC',
+ closeCallback: function() {$('.ui-dialog').removeClass('ui-dialog-aboutIITC');}
+ });
}
diff --git a/style.css b/style.css
index c01f4147..c4db1026 100644
--- a/style.css
+++ b/style.css
@@ -503,7 +503,7 @@ h3 {
.mods span {
background-color: rgba(0, 0, 0, 0.3);
- /* can’t use inline-block because Webkit’s implementation is buggy and
+ /* can’t use inline-block because Webkit's implementation is buggy and
* introduces additional margins in random cases. No clear necessary,
* as that’s solved by setting height on .mods. */
display: block;
@@ -666,7 +666,6 @@ h3 {
font-size: 16px;
}
-
/* update status */
#updatestatus {
background-color: rgba(8, 48, 78, 0.9);
@@ -712,6 +711,25 @@ h3 {
padding: 2px 4px;
}
+.ui-widget-overlay {
+ height: 100%;
+ left: 0;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 10000;
+ background: #444;
+ opacity: 0.6;
+}
+
+.ui-modal {
+ z-index: 10001 !important;
+}
+
+.ui-tooltip {
+ z-index: 10002 !important;
+}
+
.ui-tooltip, .ui-dialog a {
color: #FFCE00;
}
@@ -721,15 +739,8 @@ h3 {
border-radius: 2px;
}
-.ui-widget-overlay {
- height: 100%;
- left: 0;
- position: fixed;
- top: 0;
- width: 100%;
- z-index:9998;
- background: #444;
- opacity: 0.6;
+.ui-dialog-modal .ui-dialog-titlebar-close {
+ display: none;
}
.ui-dialog-titlebar {
@@ -743,10 +754,26 @@ h3 {
font-weight: bold;
}
-.ui-dialog-titlebar-close {
+.ui-dialog-titlebar-button {
position: absolute;
- right: .2em;
- top: 0;
+ float: left;
+ width: 17px;
+ height: 19px;
+ top: 2px;
+ cursor: pointer;
+ color: #FFCE00;
+ font-family: "Arial", sans;
+ font-size: 14px;
+ border-style: none;
+ background-color: rgba(0, 0, 0, 0);
+}
+
+.ui-dialog-titlebar-button-close {
+ right: 4px;
+}
+
+.ui-dialog-titlebar-button-collapse {
+ right: 28px;
}
.ui-dialog-content {
@@ -757,6 +784,10 @@ h3 {
max-width: 700px !important;
}
+.ui-dialog-content-hidden {
+ display: none !important;
+}
+
.ui-dialog-buttonpane {
padding: 12px;
border-top: 1px solid #20A8B1;
@@ -798,7 +829,7 @@ td + td {
}
/* redeem results *****************************************************/
-.redeem-result {
+.redeem-result-table {
font-size: 14px;
font-family: Roboto, Arial, Helvetica, sans-serif;
table-layout: fixed;
@@ -809,6 +840,10 @@ td + td {
text-align: right;
}
+.redeem-result-html {
+ font-family: Inconsolata, Consolas, Menlo, "Courier New", monospace;
+}
+
.pl_nudge_date {
background-color: #724510;
border-left: 1px solid #ffd652;