partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

TipOfTheDayWindow.js (8254B)


      1 /**
      2  * This class represents the tip of the day window and its logic.
      3  */
      4 Ext.define("PartKeepr.TipOfTheDayWindow", {
      5     extend: 'Ext.window.Window',
      6 
      7     /* Defines the title template. */
      8     titleTemplate: i18n("Tip of the Day"),
      9 
     10     /* Cosmetic settings */
     11     width: 600,
     12     height: 300,
     13 
     14     minWidth: 600,
     15     minHeight: 300,
     16 
     17     layout: 'fit',
     18 
     19     /**
     20      * Stores the currently displayed tip, or null if none is displayed
     21      * @var Ext.data.Record
     22      */
     23     currentTip: null,
     24 
     25     /**
     26      * Holds an instance of the TipOfTheDay store.
     27      */
     28     tipStore: null,
     29 
     30     /**
     31      * Holds an instance of the TipOfTheDayHistory store
     32      */
     33     tipHistoryStore: null,
     34 
     35     /**
     36      * Initializes the window. Adds the iframe used for displaying tips, as well
     37      * as the user controls (prev/next buttons, config checkboxes).
     38      */
     39     initComponent: function ()
     40     {
     41         // Initialize the window with the title template
     42         this.title = this.titleTemplate;
     43 
     44         // Set the tip store
     45         this.tipStore = Ext.data.StoreManager.lookup('TipOfTheDayStore');
     46         this.tipHistoryStore = Ext.data.StoreManager.lookup('TipOfTheDayHistoryStore');
     47 
     48         // Set the tip display iframe and add it to the items
     49         this.tipDisplay = Ext.create("Ext.ux.IFrame", {
     50             border: false
     51         });
     52 
     53         this.items = this.tipDisplay;
     54 
     55         // Initialize previous and next buttons
     56         this.previousButton = Ext.create("Ext.button.Button", {
     57             text: i18n("Previous Tip"),
     58             handler: Ext.bind(this.displayPreviousTip, this),
     59             iconCls: 'partkeepr-icon tip_previous',
     60             disabled: true
     61         });
     62 
     63         this.nextButton = Ext.create("Ext.button.Button", {
     64             text: i18n("Next Tip"),
     65             iconCls: 'partkeepr-icon tip_next',
     66             handler: Ext.bind(this.displayNextTip, this)
     67         });
     68 
     69         // Initializes the "show tips on login" checkbox as well as the "show read tips" checkbox
     70         this.showTipsCheckbox = Ext.create("Ext.form.field.Checkbox", {
     71             boxLabel: i18n("Show Tips on login"),
     72             handler: Ext.bind(this.showTipsHandler, this)
     73         });
     74 
     75         this.displayReadTipsCheckbox = Ext.create("Ext.form.field.Checkbox", {
     76             boxLabel: i18n("Show read tips"),
     77             handler: Ext.bind(this.showReadTipsHandler, this)
     78         });
     79 
     80         // Initialize the "show tips" checkbox with the user preference
     81         if (PartKeepr.getApplication().getUserPreference("partkeepr.tipoftheday.showtips") === false) {
     82             this.showTipsCheckbox.setValue(false);
     83         } else {
     84             this.showTipsCheckbox.setValue(true);
     85         }
     86 
     87         // Append the controls to the bottom toolbar
     88         this.dockedItems = [
     89             {
     90                 xtype: 'toolbar',
     91                 dock: 'bottom',
     92                 ui: 'footer',
     93                 defaults: {minWidth: 100},
     94                 pack: 'start',
     95                 items: [
     96                     this.previousButton,
     97                     this.nextButton,
     98                     '->',
     99                     this.showTipsCheckbox,
    100                     this.displayReadTipsCheckbox
    101                 ]
    102             }
    103         ];
    104 
    105         // Auto-load the next unread tip on window display
    106         this.updateFilter();
    107         this.currentTip = this.tipStore.getAt(0);
    108         this.on("show", this.displayTip, this);
    109 
    110         // Window destroy handler
    111         this.on("destroy", this.onDestroy, this);
    112         this.callParent();
    113     },
    114     /**
    115      * Displays the previous tip
    116      */
    117     displayPreviousTip: function ()
    118     {
    119         var idx = this.tipStore.indexOf(this.currentTip);
    120         this.currentTip = this.tipStore.getAt(idx - 1);
    121 
    122         if (this.currentTip === null) {
    123             this.currentTip = this.tipStore.getAt(0);
    124         }
    125         this.displayTip(this.currentTip);
    126     },
    127     /**
    128      * Displays the next tip
    129      */
    130     displayNextTip: function ()
    131     {
    132         var idx = this.tipStore.indexOf(this.currentTip);
    133         this.currentTip = this.tipStore.getAt(idx + 1);
    134 
    135         if (this.currentTip === null) {
    136             this.currentTip = this.tipStore.getAt(0);
    137         }
    138         this.displayTip(this.currentTip);
    139     },
    140     /**
    141      * Updates the filter for the tip store to exclude read tips.
    142      */
    143     updateFilter: function ()
    144     {
    145         this.tipStore.clearFilter();
    146 
    147         if (this.displayReadTipsCheckbox.getValue() === true) {
    148             return;
    149         }
    150         var filterItems = [];
    151 
    152         this.tipHistoryStore.each(function (record)
    153         {
    154             filterItems.push(record.get("name"));
    155         });
    156 
    157         var tipFilter = Ext.create("PartKeepr.util.Filter", {
    158             property: "name",
    159             operator: "notin",
    160             value: filterItems
    161         });
    162 
    163         this.tipStore.addFilter(tipFilter);
    164     },
    165     /**
    166      * If the "show read tips" checkbox was clicked, update the buttons
    167      * to reflect the tip navigation.
    168      */
    169     showReadTipsHandler: function ()
    170     {
    171         this.updateFilter();
    172         this.updateButtons(this.currentTip);
    173     },
    174     /**
    175      * Destroy handler. Removes the "read tip" timer.
    176      */
    177     onDestroy: function ()
    178     {
    179         this.cancelReadTimer();
    180     },
    181     /**
    182      * Cancels the read timer.
    183      */
    184     cancelReadTimer: function ()
    185     {
    186         if (this.markAsReadTask) {
    187             this.markAsReadTask.cancel();
    188         }
    189     },
    190     /**
    191      * Handler when the "show tips" checkbox was clicked.
    192      */
    193     showTipsHandler: function (checkbox, checked)
    194     {
    195         PartKeepr.getApplication().setUserPreference("partkeepr.tipoftheday.showtips", checked);
    196     },
    197     /**
    198      * Displays a specific tip of the day.
    199      * @param record The record which contains the information regarding the tip
    200      */
    201     displayTip: function ()
    202     {
    203         if (!this.currentTip) {
    204             return;
    205         }
    206 
    207         // Cancel the old read timer
    208         this.cancelReadTimer();
    209 
    210         // Update buttons to reflect position
    211         this.updateButtons(this.currentTip);
    212 
    213         // Set the title to the tip name
    214         this.setTitle(this.titleTemplate + ": " + this.currentTip.get("name"));
    215 
    216         // Set iframe to the tip url
    217         this.tipDisplay.load(
    218             sprintf(PartKeepr.getApplication().getParameter("tip_of_the_day_uri"), this.currentTip.get("name")));
    219 
    220         // Fire up delayed task to mark the tip as read
    221         if (this.markAsReadTask) {
    222             this.markAsReadTask.cancel();
    223         }
    224 
    225         this.markAsReadTask = new Ext.util.DelayedTask(this.markTipRead, this);
    226         this.markAsReadTask.delay(5000);
    227 
    228     },
    229     /**
    230      * Updates the navigation buttons.
    231      *
    232      * This method has two modes, depending on which state the "show read tips" checkbox is in.
    233      * @param record The currently displayed tip
    234      */
    235     updateButtons: function (record)
    236     {
    237         if (this.tipStore.indexOf(record) > 0) {
    238             this.previousButton.enable();
    239         } else {
    240             this.previousButton.disable();
    241         }
    242 
    243         if (this.tipStore.indexOf(record) === this.tipStore.getCount() - 1) {
    244             this.nextButton.disable();
    245         } else {
    246             this.nextButton.enable();
    247         }
    248 
    249     },
    250     /**
    251      * Marks the current tip as read. Commits the information to the server.
    252      */
    253     markTipRead: function ()
    254     {
    255         this.currentTip.callPutAction("markTipRead", {}, Ext.bind(this.onMarkTipRead, this));
    256     },
    257     /**
    258      * Callback for when the markTipRead action has been completed. Re-loads the history store
    259      */
    260     onMarkTipRead: function ()
    261     {
    262         this.tipHistoryStore.load({
    263             scope: this,
    264             callback: this.onHistoryStoreLoaded
    265         });
    266     },
    267     /**
    268      * Callback for when the history store has been loaded. Updates the filter
    269      */
    270     onHistoryStoreLoaded: function ()
    271     {
    272         this.updateFilter();
    273     },
    274     /**
    275      * Returns if there are tips in the tip database which aren't read.
    276      *
    277      * @return {Boolean} True if there are tips available, false otherwise
    278      */
    279     hasTips: function ()
    280     {
    281         if (this.tipStore.count() > 0) {
    282             return true;
    283         } else {
    284             return false;
    285         }
    286 
    287     }
    288 });