Plugin Directory

Changeset 1750923


Ignore:
Timestamp:
10/23/2017 06:37:33 AM (8 years ago)
Author:
Uncategorized Creations
Message:

Version 1.2

Location:
wp-appkit/trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • wp-appkit/trunk/app/core/app.js

    r1634492 r1750923  
    9494       * @param data see models/custom-page.js for data fields
    9595       */
    96       app.showCustomPage = function(template,data,id){
     96      app.showCustomPage = function(template,data,fragment,silent){
    9797          var args = {template: template, data: data};
    98           if( id !== undefined ){
    99               args.id = id;
     98          if( fragment !== undefined ){
     99              args.id = fragment;
    100100          }
    101101          current_custom_page = new CustomPage(args);
    102           app.router.navigate( app.getScreenFragment( 'custom-page' ), { trigger: true } );
     102          if ( silent === true ) {
     103              app.router.execute_route_silently( app.getScreenFragment( 'custom-page' ) );
     104              app.router.navigate( fragment, { trigger: false } );
     105          } else {
     106              app.router.navigate( app.getScreenFragment( 'custom-page' ), { trigger: true } );
     107          }
    103108      };
    104109
     
    375380              var history_action = '';
    376381
    377               if( queried_screen_data.screen_type == 'list' ){
     382              if( queried_screen_data.fragment == current_screen.fragment ) {
     383                  //Redisplaying same screen: do nothing
     384                  history_action = 'none';
     385              }else if( queried_screen_data.screen_type == 'list' ){
    378386                  history_action = 'empty-then-push';
    379387              }else if( queried_screen_data.screen_type == 'single' ){
     
    894902                    comments.add( value );
    895903                } );
     904               
     905                post.set( 'nb_comments', comments.length );
     906                post.save();
     907                       
    896908                cb_ok( comments, post, item_global );
    897909            };
     
    916928    };
    917929
    918     app.getPostComments = function ( post_id, cb_ok, cb_error ) {
     930    app.getPostComments = function ( post_id, cb_ok, cb_error, force_refresh ) {
     931
     932        force_refresh = force_refresh === true;
    919933
    920934        var post_comments_memory = app.comments.get( post_id );
    921         if ( post_comments_memory ) {
    922 
     935        if ( post_comments_memory && !force_refresh ) {
     936           
    923937            var post_comments = post_comments_memory.get( 'post_comments' );
    924938            var post = post_comments_memory.get( 'post' );
     
    930944
    931945        } else {
     946           
    932947            fetchPostComments(
    933948                post_id,
     
    13431358        var auto_interpret_result = !options.hasOwnProperty('auto_interpret_result') || options.auto_interpret_result === true;
    13441359
    1345         //interpretation_type defaults to 'update' :
     1360        //interpretation_type defaults to 'replace-keep-global-items' :
    13461361        var interpretation_type = options.hasOwnProperty('type') ? options.type : 'replace-keep-global-items';
    13471362
     
    15091524        $.ajax( ajax_args );
    15101525    };
     1526   
     1527      app.getPageComponentByPageId = function( page_id, default_to_first_component ) {
     1528            var page_component = _.find( this.getComponents(), function( component ){
     1529                return component.type === 'page' && component.global === 'pages' && component.data.root_id === page_id;
     1530            } );
     1531           
     1532            if ( !page_component && default_to_first_component === true ) {
     1533                page_component = this.findFirstComponentOfType( 'page' );
     1534            }
     1535           
     1536            return page_component;
     1537      };
    15111538
    15121539      app.getComponentData = function(component_id){
     
    16841711          return item;
    16851712      };
     1713     
     1714        /**
     1715         * Retrieve items (posts/pages etc) from remote server and merge them into existing app's items.
     1716         *
     1717         * @param Array items array of ids of pages/posts to retrieve.
     1718         * @param JSON Object options:
     1719         *  - component_id:   Int (optional) Slug of the component we want to retrieve items for.
     1720         *                    If not provided, the first component of "component_type" found
     1721         *                    will be used.
     1722         *  - component_type: String (optional) Type of component ("posts-list", "pages") we want to
     1723         *                    retrieve items for. Only useful if component_id is not provided.
     1724         *                    If not provided, defaults to "posts-list".
     1725         *  - persistent:     Boolean (optional) Whether to persist retrieved items to local storage.
     1726         *                    Defaults to true.
     1727         *  - success:        Callback (optional) Called if items are retrieved successfully
     1728         *  - error:          Callback (optional) Called if an error occured while retrieving items from server.
     1729         *                    App error events are also triggered in that case.
     1730         */
     1731        app.getItemsFromRemote = function ( items_ids, options ) {
     1732
     1733            options = options || {};
     1734           
     1735            Utils.log('Retrieving items from remote server.', items_ids);
     1736           
     1737            //Posts/pages/items can only be retrieved by component, as their content is formatted
     1738            //according to the component type they belong to.
     1739            var component = null;
     1740            if ( options.component_id ) {
     1741                if ( this.components.get( options.component_id ) ) {
     1742                    component = this.components.get( options.component_id );
     1743                } else {
     1744                    this.triggerError(
     1745                        'get-items:remote:wrong-component-given',
     1746                        { type:'wrong-data', where:'app::getItemsFromRemote', message: 'Provided component not found ['+ options.component_id +']', data: { options: options, items_ids: items_ids } },
     1747                        options.error
     1748                    );
     1749                    return;
     1750                }
     1751            }
     1752           
     1753            if ( !component ) {
     1754                var component_type = options.component_type ? options.component_type : 'posts-list';
     1755                component = this.findFirstComponentOfType( component_type );
     1756            }
     1757
     1758            if ( component ) {
     1759
     1760                var _this = this;
     1761               
     1762                var persistent = !options.persistent || options.persistent === true;
     1763
     1764                //Call liveQuery to retrieve the given items from server and store them in local storage:
     1765                this.liveQuery(
     1766                    {
     1767                        wpak_component_slug: component.id,
     1768                        wpak_query_action: 'get-items',
     1769                        wpak_items_ids: items_ids
     1770                    },
     1771                    function( answer, results ){
     1772
     1773                        var items_found = _.find( results, function( result ) {
     1774                            return result.data.new_items.length > 0;
     1775                        } );
     1776
     1777                        if ( items_found ) {
     1778                            Utils.log('Items retrieved successfully from remote server.', items_ids, results);
     1779                            if ( options.success ) {
     1780                                options.success( answer, component, results );
     1781                            }
     1782                        } else {
     1783                            //Requested posts where not found. Trigger error
     1784                            if ( options.error ) {
     1785                                _this.triggerError(
     1786                                    'get-items:remote:no-item-found',
     1787                                    { type:'not-found', where:'app::getItemsFromRemote', message: 'Requested items not found', data: { options: options, items_ids: items_ids } },
     1788                                    options.error
     1789                                );
     1790                            }
     1791                        }
     1792
     1793                    },
     1794                    function( error ){
     1795                        //liveQuery error: error event has been triggered in liveQuery,
     1796                        //simply call the error callback here:
     1797                        if ( options.error ) {
     1798                            options.error( error );
     1799                        }
     1800                    },
     1801                    {
     1802                        type: 'update',
     1803                        persistent: persistent
     1804                    }
     1805                );
     1806
     1807            } else {
     1808                app.triggerError(
     1809                    'get-items:remote:wrong-component',
     1810                    { type:'wrong-data', where:'app::getItemsFromRemote', message: 'Could not find a valid component', data: { options: options, items_ids: items_ids } },
     1811                    options.error
     1812                );
     1813            }
     1814        };
     1815       
     1816        app.findFirstComponentOfType = function( component_type ) {
     1817            return _.findWhere( this.getComponents(), { type: component_type } )
     1818        };
     1819       
     1820        app.loadRouteItemFromRemote = function( item_id, item_global, component_type, options ){
     1821            var load_from_remote =  Hooks.applyFilters('load-unfound-items-from-remote', true, [item_id,item_global]);
     1822            if ( load_from_remote ) {
     1823
     1824                /**
     1825                 * Use 'load-unfound-items-component-id' and 'load-unfound-items-component-type' to customize
     1826                 * which component is used to retrieve the item from remote.
     1827                 * Default is the first "posts-list" component found.
     1828                 */
     1829                var item_component_id = Hooks.applyFilters('load-unfound-items-component-id', '', [item_id,item_global]);
     1830                var item_component_type = Hooks.applyFilters('load-unfound-items-component-type', component_type, [item_id,item_global]);
     1831
     1832                this.triggerInfo( 'load-item-from-remote:start', {
     1833                    item_id: item_id, item_global: item_global, item_component_id: item_component_id, item_component_type: item_component_type
     1834                } );
     1835               
     1836                var global = this.globals[item_global];
     1837               
     1838                var _this = this;
     1839
     1840                this.getItemsFromRemote( [item_id], {
     1841                    component_id: item_component_id,
     1842                    component_type: item_component_type,
     1843                    success: function( answer, component, results ) {
     1844                        var item = global.get(item_id);
     1845
     1846                        _this.triggerInfo( 'load-item-from-remote:stop', {
     1847                            item_id: item_id, item_global: item_global, item: item,
     1848                            item_component_id: item_component_id, item_component_type: item_component_type,
     1849                            success: !!item
     1850                        } );
     1851
     1852                        if ( item ) {
     1853
     1854                            //Success!
     1855                            if ( options.success ) {
     1856                                options.success( item, component );
     1857                            }
     1858
     1859                        } else {
     1860                            Utils.log('loadRouteItemFromRemote : unexpected error "'+ item_id +'" not found in global "'+ item_global +'" even after remote call.');
     1861
     1862                            _this.triggerError(
     1863                                'get-items:remote:item-not-found-in-global',
     1864                                { type:'not-found', where:'app::loadRouteItemFromRemote', message: 'Requested items not found', data: {
     1865                                    item_id: item_id, item_global: item_global, item: item,
     1866                                    item_component_id: item_component_id, item_component_type: item_component_type
     1867                                } }
     1868                            );
     1869                   
     1870                            if ( options.error ) {
     1871                                options.error();
     1872                            }
     1873                        }
     1874                    },
     1875                    error: function() {
     1876
     1877                        _this.triggerInfo( 'load-item-from-remote:stop', {
     1878                            item_id: item_id, item_global: item_global,
     1879                            item_component_id: item_component_id, item_component_type: item_component_type,
     1880                            success: false
     1881                        } );
     1882
     1883                        if ( options.error ) {
     1884                            options.error();
     1885                        }
     1886                    }
     1887                   
     1888                } );
     1889
     1890            } else {
     1891                if ( options.error ) {
     1892                    options.error();
     1893                }
     1894            }
     1895        };
    16861896
    16871897      /**
  • wp-appkit/trunk/app/core/models/comments.js

    r1634492 r1750923  
    3030        model: PostComments,
    3131        addPostComments: function( post_id, post, item_global, comments ) {
    32             this.add( { id: post_id, post: post, item_global: item_global, post_comments: comments.clone() } );
     32            this.add( { id: post_id, post: post, item_global: item_global, post_comments: comments.clone() }, { merge: true } );
    3333        }
    3434    } );
  • wp-appkit/trunk/app/core/router.js

    r1634492 r1750923  
    2626            "single/:global/:id" : "single",
    2727            "page/:component_id/:page_id" : "page",
     28            "page/:page_id" : "page_no_component",
    2829            "comments-:post_id" : "comments",
    2930            "component-:id" : "component",
     
    106107            route_asked = 'single/'+ item_global +'/'+ item_id;
    107108
     109            var show_single = function( item ) {
     110                var item_json = item.toJSON();
     111                var item_data = item_global == 'posts' ? {post:item_json} : {item:item_json};
     112
     113                if( check_route('single/'+ item_global +'/'+ item_id) ){
     114                    RegionManager.show(
     115                        'single',
     116                        {item:item,global:item_global},
     117                        {screen_type:'single',component_id:'',item_id:parseInt(item_id),global:item_global,data:item_data,label:item_json.title}
     118                    );
     119                }
     120            };
     121
    108122            require(["core/app"],function(App){
    109123                var global = App.globals[item_global];
     
    111125                    var item = global.get(item_id);
    112126                    if( item ){
    113                         var item_json = item.toJSON();
    114                         var item_data = item_global == 'posts' ? {post:item_json} : {item:item_json};
    115 
    116                         if( check_route('single/'+ item_global +'/'+ item_id) ){
    117                             RegionManager.show(
    118                                 'single',
    119                                 {item:item,global:item_global},
    120                                 {screen_type:'single',component_id:'',item_id:parseInt(item_id),global:item_global,data:item_data,label:item_json.title}
    121                             );
    122                         }
    123 
     127                       
     128                        show_single( item );
     129                       
    124130                    }else{
    125                         Utils.log('Error : router single route : item with id "'+ item_id +'" not found in global "'+ item_global +'".');
    126                         App.router.default_route();
     131                       
     132                        Utils.log('Router single route : item with id "'+ item_id +'" not found in global "'+ item_global +'".');
     133                       
     134                        App.loadRouteItemFromRemote( item_id, item_global, 'posts-list', {
     135                            success: function( item ) {
     136                                show_single( item );
     137                            },
     138                            error: function() {
     139                                App.router.default_route();
     140                            }
     141                        } );
     142                       
    127143                    }
    128144                }else{
     
    136152            route_asked = 'page/'+ component_id +'/'+ page_id;
    137153
     154            var item_global = 'pages';
     155               
     156            var _this = this;   
     157           
    138158            require(["core/app"],function(App){
    139                 var item_global = 'pages';
     159               
     160                var show_page = function( item, page_component_id ) {
     161                   
     162                    //To allow page route with no component (#page/[page_id]):
     163                    if ( page_component_id === 'wpak-page-component-placeholder' ) {
     164                        //If the page was loaded dynamically, it has no corresponding component,
     165                        //so we pass true to getPageComponentByPageId() so that the first page component
     166                        //found is used in that case:
     167                        var page_component = App.getPageComponentByPageId( item.get('id'), true );
     168                        if ( page_component ) {
     169                            page_component_id = page_component.id;
     170                        }
     171                    }
     172                   
     173                    var component = App.getComponentData( page_component_id );
     174
     175                    if( component ){
     176
     177                        var item_data = {
     178                            post:item.toJSON(),
     179                            is_tree_page:component.data.is_tree,
     180                            is_tree_root:(page_id == component.data.root_id),
     181                            root_id:component.data.root_id,
     182                            root_depth:component.data.root_depth
     183                        };
     184
     185                        //This is still component_id to check the route and not page_component_id, to handle the case
     186                        //where the page was not in the app and was retrieved from remote.
     187                        if( check_route('page/'+ component_id +'/'+ page_id) ) {
     188                            RegionManager.show(
     189                                'page',
     190                                {item:item,global:item_global},
     191                                {screen_type:'page',component_id:page_component_id,item_id:parseInt(page_id),global:item_global,data:item_data,label:item_data.post.title}
     192                            );
     193                        }
     194
     195                    }else{
     196                        Utils.log('Error : router : page route : component with id "'+ page_component_id +'" not found');
     197                        _this.default_route();
     198                    }
     199                };
     200               
    140201                var global = App.globals[item_global];
    141202                if( global ){
    142203                    var item = global.get(page_id);
    143204                    if( item ){
    144                         var component = App.getComponentData(component_id);
    145                         if( component ){
    146 
    147                             var item_data = {
    148                                 post:item.toJSON(),
    149                                 is_tree_page:component.data.is_tree,
    150                                 is_tree_root:(page_id == component.data.root_id),
    151                                 root_id:component.data.root_id,
    152                                 root_depth:component.data.root_depth
    153                             };
    154 
    155                             if( check_route('page/'+ component_id +'/'+ page_id) ){
    156                                 RegionManager.show(
    157                                     'page',
    158                                     {item:item,global:item_global},
    159                                     {screen_type:'page',component_id:component_id,item_id:parseInt(page_id),global:item_global,data:item_data,label:item_data.post.title}
    160                                 );
     205                        show_page( item, component_id );
     206                    }else{
     207                       
     208                        Utils.log('Error : router : page route : item with id "'+ page_id +'" not found in global "'+ item_global +'".');
     209                       
     210                        App.loadRouteItemFromRemote( page_id, item_global, 'page', {
     211                            success: function( item, item_component ) {
     212                                show_page( item, item_component.id );
     213                            },
     214                            error: function() {
     215                                App.router.default_route();
    161216                            }
    162 
    163                         }else{
    164                             Utils.log('Error : router : page route : component with id "'+ component_id +'" not found');
    165                             App.router.default_route();
    166                         }
    167                     }else{
    168                         Utils.log('Error : router : page route : item with id "'+ page_id +'" not found in global "'+ item_global +'".');
    169                         App.router.default_route();
     217                        } );
     218                       
    170219                    }
    171220                }else{
     
    175224            });
    176225        },
     226       
     227        page_no_component: function ( page_id ) {
     228            this.page( 'wpak-page-component-placeholder', page_id );
     229        },
    177230
    178231        comments: function ( post_id ) {
     
    246299                if( !_.isEmpty(custom_route) ){
    247300                    fragment_not_found = '';
    248                     App.showCustomPage(custom_route.template,custom_route.data,fragment);
     301                    App.showCustomPage(custom_route.template,custom_route.data,fragment,true);
    249302                }
    250303
     
    254307            });
    255308
    256         }
     309        },
     310       
     311        /**
     312         * Execute router's method corresponding to the given route without
     313         * changing current url or fragment.
     314         * Used for custom routes.
     315         */
     316        execute_route_silently: function ( route ) {
     317
     318            var fragment = Backbone.history.getFragment( route );
     319            var route_handler = _.find( Backbone.history.handlers, function ( handler ) {
     320                return handler.route.test( fragment );
     321            } );
     322
     323            if ( route_handler !== undefined ) {
     324                this.execute( route_handler.callback, [ fragment ], '' );
     325            } else {
     326                Utils.log( 'Router.js error: execute_route_silently: route not found.' );
     327            }
     328
     329        }
     330
    257331
    258332    });
  • wp-appkit/trunk/app/core/theme-app.js

    r1703622 r1750923  
    1010            Backbone = require( 'backbone' ),
    1111            RegionManager = require( 'core/region-manager' ),
    12             Utils = require( 'core/app-utils' ),
    13             Config = require( 'root/config' ),
    1412            Messages = require( 'core/messages' ),
    1513            App = require( 'core/app' ),
     
    332330        var current_view = RegionManager.getCurrentView();
    333331        current_view.render();
     332    };
     333   
     334    /**
     335     * Retrieve current Backbone view object
     336     */
     337    themeApp.getCurrentView = function() {
     338        var current_view = RegionManager.getCurrentView();
     339        return current_view;
    334340    };
    335341
     
    436442
    437443    };
     444   
     445    /**
     446     * When on a comments screen, reloads the comments for the current post and
     447     * re-renders the view to display new comments.
     448     *
     449     * @param {function} cb_ok      What to do when comment screen was updated successfully
     450     * @param {function} cb_error   What to do if an error occurs while updating comment screen
     451     */
     452    themeApp.updateCurrentCommentScreen = function ( cb_ok, cb_error ) {
     453       
     454        var current_screen_info = this.getCurrentScreenObject();
     455       
     456        if ( current_screen_info.screen_type !== 'comments' ) {
     457            return;
     458        }
     459
     460        //Retrieve post id corresponding to the current comments screen:
     461        var post_id = current_screen_info.post.id;
     462
     463        var _this = this;
     464       
     465        //Reload post comments from server:
     466        App.getPostComments(
     467            post_id,
     468            function ( comments, post ) {
     469                //New comments loaded successfully             
     470               
     471                //Update current view's comments with new comments
     472                var comments_view = RegionManager.getCurrentView();
     473                comments_view.comments = comments;
     474               
     475                //Rerender screen:
     476                _this.rerenderCurrentScreen();
     477               
     478                cb_ok( comments, post );
     479            },
     480            function ( error ) {
     481                cb_error( error );
     482            },
     483            true //To force post comments cache flush
     484        );
     485    }
    438486
    439487    /************************************************
     
    770818     */
    771819
    772     themeApp.showCustomPage = function( template, data, id ) {
     820    themeApp.showCustomPage = function( template, data, fragment, silent ) {
    773821        if ( template === undefined ) {
    774822            template = 'custom';
     
    777825            data = {};
    778826        }
    779         if ( id === undefined ) {
    780             id = 'auto-custom-page';
    781         }
    782         App.showCustomPage( template, data, id );
     827        if ( fragment === undefined ) {
     828            fragment = 'auto-custom-page';
     829        }
     830        if ( silent === undefined ) {
     831            silent = true;
     832        }
     833        App.showCustomPage( template, data, fragment, silent );
    783834    };
    784835
     
    834885     * @param {int} item_id Post ID of the post to retrieve
    835886     * @param {string} global_key (Optional) global to retrieve the item from: 'posts' (default) or 'pages'.
    836      * @returns {JSON Object} item (post or page) object
     887     * @returns {JSON Object | null} item (post or page) object if found, null if no post found with the given item_id.
    837888     */
    838889    themeApp.getItem = function( item_id, global_key ) {
     
    841892
    842893        return App.getGlobalItem( global_key, item_id );
     894    };
     895   
     896    /**
     897    * Retrieve items (posts/pages etc) from remote server and merge them into existing app's items.
     898    *
     899    * @param Array items array of ids of pages/posts to retrieve.
     900    * @param JSON Object options:
     901    *  - component_id:   Int (optional) Slug of the component we want to retrieve items for.
     902    *                    If not provided, the first component of "component_type" found
     903    *                    will be used.
     904    *  - component_type: String (optional) Type of component ("posts-list", "pages") we want to
     905    *                    retrieve items for. Only useful if component_id is not provided.
     906    *                    If not provided, defaults to "posts-list".
     907    *  - persistent:     Boolean (optional) Whether to persist retrieved items to local storage.
     908    *                    Defaults to true.
     909    *  - success:        Callback (optional) Called if items are retrieved successfully
     910    *  - error:          Callback (optional) Called if an error occured while retrieving items from server.
     911    *                    App error events are also triggered in that case.
     912    */
     913    themeApp.getItemsFromRemote = function( items_ids, options ) {
     914        App.getItemsFromRemote( items_ids, options );
    843915    };
    844916
  • wp-appkit/trunk/default-themes/q-android/js/functions.js

    r1634492 r1750923  
    2828    ], function($,App,Storage,TemplateTags,Config,Moment,Velocity) {
    2929
    30    
    31    
     30
    3231    /*
    3332     * App's parameters
     
    114113    } );
    115114   
     115    //@desc Memorize the last history action so that we can decide what to do when
     116    //doing "single to single" transitions:
     117    var last_history_action = '';
     118   
    116119    // @desc Catch if we're going to a single and coming from a single (it is the case when clicking on a post in the last posts widget at the bottom of a post)
    117120    // Update properly the history stack
     
    126129        }
    127130       
     131        last_history_action = history_action;
     132       
    128133        // Return the proper history action
    129134        return history_action;
     
    131136    });
    132137
    133 
    134    
     138    // @desc Handle "single to single" transition:
     139    App.filter( 'transition-direction', function( transition, current_screen, next_screen ){
     140       
     141        if( current_screen.screen_type === 'single' && next_screen.screen_type === 'single' ) {
     142            if ( last_history_action === 'push' ) {
     143                transition = 'next-screen';
     144            } else {
     145                transition = 'previous-screen';
     146            }
     147           
     148        }
     149       
     150        return transition;
     151    });
     152
     153    // @desc Handle transitions for deeplinks:
     154    App.filter( 'transition-direction', function( transition, current_screen, next_screen ){
     155
     156        //Display single in a slide up panel when opening from deeplinks:
     157        if( next_screen.screen_type === 'single' && _.isEmpty( current_screen ) ) {
     158                transition = 'next-screen';
     159        }
     160
     161        return transition;
     162    });
     163
    135164    /*
    136165     * Actions
    137166     */
    138    
     167   
    139168    // @desc Detect transition types (aka directions) and launch corresponding animations
    140169    App.action( 'screen-transition', function( $wrapper, $current, $next, current_screen, next_screen, $deferred ) {
     
    238267        $current.remove();
    239268        $wrapper.empty().append( $next );
     269        if ( $currentContainer ) {
     270            removeContainer($currentContainer);
     271        }
    240272        $deferred.resolve();
    241273       
     
    285317
    286318    });
     319   
     320    // @desc The app starts retrieving a new post from remote server
     321    App.on('info:load-item-from-remote:start',function(){
     322        // Start refresh icon animation
     323        $("#refresh-button").hide();
     324        $(".loading-from-remote-button").show();
     325    });
     326   
     327    // @desc A new post was retrieved from remote server
     328    App.on('info:load-item-from-remote:stop',function(){
     329        // Stop refresh icon animation
     330        $(".loading-from-remote-button").hide();
     331        $("#refresh-button").show();
     332    });
    287333
    288334    // @desc An error occurs
     
    345391        if (current_screen.screen_type=="single" || current_screen.screen_type=="page") {
    346392
    347             // Redirect all content hyperlinks clicks
    348             // @todo: put it into prepareContent()
    349             $("#app-layout").on("click", ".single-content a", openInBrowser);
    350            
    351393            // Make any necessary modification to post/page content
    352394            prepareContent( currentScreenObject );
     
    464506    $('#app-layout').on( 'touchend', '.has-ripple-feedback', rippleItemTapOff );
    465507   
    466    
     508    // Redirect all content hyperlinks clicks
     509    // @todo: put it into prepareContent()
     510    $("#app-layout").on("click", ".single-content a", openInBrowser);
    467511   
    468512    /*
     
    749793        } else { // href begins with # (ie. it's an internal link)
    750794           
    751             App.navigate( href ); // Navigate to the corresponding screen
    752            
    753         }
    754        
     795            App.navigate( href );
     796           
     797        }
    755798
    756799    }
  • wp-appkit/trunk/default-themes/q-android/layout.html

    r1634492 r1750923  
    1313        <div id="menu-button" class="menu-button"></div>
    1414        <div id="refresh-button" class="refresh-off"></div>
     15        <div class="loading-from-remote-button refresh-on" style="display:none"></div>
    1516        <h1></h1>
    1617    </div>
     
    2627        <div id="panel-header" class="panel-header has-ripple-feedback ripple-small">
    2728            <div id="back-button" class="back-button"></div>
     29            <div class="loading-from-remote-button refresh-on" style="display:none"></div>
    2830            <h1></h1>
    2931        </div>
  • wp-appkit/trunk/default-themes/q-android/readme.md

    r1703622 r1750923  
    22Theme Name: Q for Android
    33Description:  A clean and simple Android app news theme featuring: back button, comments, content refresh, custom post types, embeds, infinite list, latest posts, native sharing, network detection, off-canvas menu, offline content, pages, posts, pull to refresh, responsive, status bar, touch, transitions
    4 Version: 1.0.5
     4Version: 1.0.6
    55Theme URI: https://github.com/uncatcrea/q-android
    66Author: Uncategorized Creations         
  • wp-appkit/trunk/default-themes/q-android/single.html

    r1634492 r1750923  
    3939    <div id="single-content" class="single-content">
    4040
    41             <%= post.content %>
     41        <%= post.content %>
    4242
    43     </div>
     43    </div>
    4444   
    4545</div>
  • wp-appkit/trunk/default-themes/q-ios/js/functions.js

    r1634492 r1750923  
    104104       
    105105    } );
    106 
     106   
     107    //@desc Memorize the last history action so that we can decide what to do when
     108    //doing "single to single" transitions:
     109    var last_history_action = '';
     110
     111    // @desc Catch if we're going to a single and coming from a single (it is the case when clicking on a post in the last posts widget at the bottom of a post)
     112    // Update properly the history stack
     113    App.filter( 'make-history', function( history_action, history_stack, queried_screen, current_screen, previous_screen ) {
     114
     115        if( queried_screen.screen_type === 'single' && current_screen.screen_type === 'single' ) {
     116            if ( ( queried_screen.item_id !== previous_screen.item_id ) ) { // Going to a single to another single that is not the one we came from
     117                history_action = 'push';
     118            } else { // Going back to the previous single
     119                history_action = 'pop';
     120            }
     121        }
     122       
     123        last_history_action = history_action;
     124       
     125        // Return the proper history action
     126        return history_action;
     127
     128    });
     129   
     130    // @desc Handle "single to single" transition:
     131    App.filter( 'transition-direction', function( transition, current_screen, next_screen ){
     132       
     133        if( current_screen.screen_type === 'single' && next_screen.screen_type === 'single' ) {
     134            if ( last_history_action === 'push' ) {
     135                transition = 'next-screen';
     136            } else {
     137                transition = 'previous-screen';
     138            }
     139           
     140        }
     141       
     142        return transition;
     143    });
     144
     145    // @desc Handle transitions for deeplinks:
     146    App.filter( 'transition-direction', function( transition, current_screen, next_screen ){
     147
     148        //Display single in a slide up panel when opening from deeplinks:
     149        if( next_screen.screen_type === 'single' && _.isEmpty( current_screen ) ) {
     150                transition = 'next-screen';
     151        }
     152
     153        return transition;
     154    });
    107155   
    108156
     
    283331    });
    284332
     333    // @desc The app starts retrieving a new post from remote server
     334    App.on('info:load-item-from-remote:start',function(){
     335        // Start refresh icon animation
     336        $("#refresh-button").removeClass("refresh-off").addClass("refresh-on");
     337    });
     338   
     339    // @desc A new post was retrieved from remote server
     340    App.on('info:load-item-from-remote:stop',function(){
     341        // Stop refresh icon animation
     342        $("#refresh-button").removeClass("refresh-on").addClass("refresh-off");
     343    });
     344
    285345    // @desc An error occurs
    286346    // @param error
  • wp-appkit/trunk/default-themes/q-ios/readme.md

    r1703622 r1750923  
    22Theme Name: Q for iOS
    33Description: A clean and simple iOS app news theme featuring: back button, content refresh, custom post types, embeds, infinite list, network detection, off-canvas menu, offline content, pages, posts, responsive, touch, transitions
    4 Version: 1.0.5
     4Version: 1.0.6
    55Theme URI: https://github.com/uncatcrea/q-ios/
    66Author: Uncategorized Creations         
  • wp-appkit/trunk/lib/components/components-bo-settings.php

    r1634492 r1750923  
    296296            }
    297297
    298             if ( is_numeric( $component_label ) ) {
    299                 $answer['message'] = __( "The component label can't be numeric.", WpAppKit::i18n_domain );
    300                 self::exit_sending_json( $answer );
    301             }
    302 
    303             $component_slug = $edit ? trim( $data['component_slug'] ) : $component_label;
     298            $component_slug = $edit ? trim( $data['component_slug'] ) : ( !is_numeric( $component_label ) ? $component_label : 'slug-'. $component_label );
    304299            $component_slug = sanitize_title_with_dashes( remove_accents( $component_slug ) );
    305300
  • wp-appkit/trunk/lib/components/components-types/page.php

    r1634492 r1750923  
    128128        foreach ( $items_ids as $post_id ) {
    129129            $post = get_post( $post_id );
    130             if( !empty($post) ) {
     130            if( !empty($post) && $post->post_status == 'publish' && $post->post_type == 'page' ) {
    131131                $posts_by_ids[$post_id] = self::get_page_data( $component, $post );
    132132            }
  • wp-appkit/trunk/lib/components/components-utils.php

    r1634492 r1750923  
    77     */
    88    public static function get_post_data( $wp_post, $component = null ) {
    9        
     9
    1010        if ( $component === null ) {
    1111            $component = new WpakComponent( 'wpak-internal', 'Internal', 'wpak-internal' );
    1212        }
    13        
     13
    1414        global $post;
    1515        $post = $wp_post;
     
    2020            'post_type' => $post->post_type,
    2121            'date' => strtotime( $post->post_date ),
    22             'title' => $post->post_title,
     22            'title' => apply_filters( 'the_title', $post->post_title, $post->ID ),
    2323            'content' => '',
    2424            'excerpt' => '',
     
    5252        $post_featured_img_id = get_post_thumbnail_id( $post->ID );
    5353        if ( !empty( $post_featured_img_id ) ) {
    54            
     54
    5555            /**
    5656             * Use this 'wpak_post_featured_image_size' to define a specific image
     
    5959             */
    6060            $featured_image_size = apply_filters( 'wpak_post_featured_image_size', 'full', $post, $component );
    61            
     61
    6262            $featured_img_src = wp_get_attachment_image_src( $post_featured_img_id, $featured_image_size );
    63             @$post_data['thumbnail']['src'] = $featured_img_src[0];
     63            $post_data['thumbnail'] = array();
     64            $post_data['thumbnail']['src'] = $featured_img_src[0];
    6465            $post_data['thumbnail']['width'] = $featured_img_src[1];
    6566            $post_data['thumbnail']['height'] = $featured_img_src[2];
     
    7980        return $post_data;
    8081    }
    81    
     82
    8283    public static function get_formated_content() {
    83        
     84
    8485        //Set global $more to 1 so that get_the_content() behaves correctly with <!-- more --> tag:
    8586        //(See wp-includes/class-wp.php::register_globals() and get_the_content())
    8687        global $more;
    87         $more = 1; 
    88        
     88        $more = 1;
     89
    8990        $post = get_post();
    9091
     
    109110            $content = strip_tags( $content, $allowed_tags );
    110111        }
    111        
     112
    112113        /**
    113114         * Filter a single post content.
  • wp-appkit/trunk/lib/themes/themes-storage.php

    r1634492 r1750923  
    9393       
    9494        if( empty($themes) || !isset( $themes['current_theme'] ) ) {
     95            if ( !is_array( $themes ) ) {
     96                $themes = array();
     97            }
    9598            $themes['current_theme'] = '';
    9699        }
  • wp-appkit/trunk/lib/themes/themes.php

    r1703622 r1750923  
    1919        'q-ios' => array(
    2020            'name' => 'Q for iOS',
    21             'version' => '1.0.5',
     21            'version' => '1.0.6',
    2222        ),
    2323
    2424        'q-android' => array(
    2525            'name' => 'Q for Android',
    26             'version' => '1.0.5',
     26            'version' => '1.0.6',
    2727        ),
    2828
  • wp-appkit/trunk/readme.txt

    r1703651 r1750923  
    44Requires at least: 4.0
    55Tested up to: 4.8
    6 Stable tag: 1.1
     6Stable tag: 1.2
    77License: GPLv2 or later
    88License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    113113
    114114Also see [changelog on github](https://github.com/uncatcrea/wp-appkit/blob/master/CHANGELOG.md) for full details.
     115
     116= 1.2 (2017-10-22) =
     117
     118*Features*
     119
     120* Automatically retrieve posts and pages from server if not in the app
     121* Allow easy comment screen refresh from theme
     122
     123*Default themes update*
     124
     125* Embed last version (1.0.6) of [Q for iOS](https://github.com/uncatcrea/q-ios/releases/tag/v1.0.6) and [Q for Android](https://github.com/uncatcrea/q-android/releases/tag/v1.0.6) default app themes
     126
     127*Bugfixes*
     128
     129* Better history management when re-triggering same route
     130* Can't go back from custom page
     131* Component's label can't be numeric
     132* Apply "the_title" filter on post title returned in webservice
     133* Warning: Illegal string offset 'current_theme'
     134* Warning on post's thumbnail array
    115135
    116136= 1.1 (2017-07-26) =
  • wp-appkit/trunk/wp-appkit.php

    r1703622 r1750923  
    44Plugin URI:  https://github.com/uncatcrea/wp-appkit
    55Description: Build Phonegap Mobile apps based on your WordPress content.
    6 Version:     1.1
     6Version:     1.2
    77Author:      Uncategorized Creations
    88Author URI:  http://getwpappkit.com
Note: See TracChangeset for help on using the changeset viewer.