diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 327b7b02..e1935fbf 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -331,7 +331,10 @@ typedef struct dvr_query_result { int dqr_alloced; } dvr_query_result_t; +typedef int (dvr_entry_filter)(dvr_entry_t *entry); + void dvr_query(dvr_query_result_t *dqr); +void dvr_query_filter(dvr_query_result_t *dqr, dvr_entry_filter filter); void dvr_query_free(dvr_query_result_t *dqr); void dvr_query_sort(dvr_query_result_t *dqr); diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index fe53120e..91165f55 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -1299,6 +1299,22 @@ dvr_query_add_entry(dvr_query_result_t *dqr, dvr_entry_t *de) dqr->dqr_array[dqr->dqr_entries++] = de; } +void +dvr_query_filter(dvr_query_result_t *dqr, dvr_entry_filter filter) +{ + dvr_entry_t *de; + + memset(dqr, 0, sizeof(dvr_query_result_t)); + + LIST_FOREACH(de, &dvrentries, de_global_link) + if (filter(de)) + dvr_query_add_entry(dqr, de); +} + +static int all_filter(dvr_entry_t *entry) +{ + return 1; +} /** * @@ -1306,15 +1322,9 @@ dvr_query_add_entry(dvr_query_result_t *dqr, dvr_entry_t *de) void dvr_query(dvr_query_result_t *dqr) { - dvr_entry_t *de; - - memset(dqr, 0, sizeof(dvr_query_result_t)); - - LIST_FOREACH(de, &dvrentries, de_global_link) - dvr_query_add_entry(dqr, de); + return dvr_query_filter(dqr, all_filter); } - /** * */ diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 6355e236..85b70c74 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -1287,7 +1287,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque) * */ static int -extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque) +extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque, dvr_entry_filter filter) { htsbuf_queue_t *hq = &hc->hc_reply; htsmsg_t *out, *array, *m; @@ -1317,7 +1317,7 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque) array = htsmsg_create_list(); - dvr_query(&dqr); + dvr_query_filter(&dqr, filter); dvr_query_sort(&dqr); @@ -1389,6 +1389,32 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque) return 0; } +static int is_dvr_entry_old(dvr_entry_t *entry) +{ + dvr_entry_sched_state_t state = entry->de_sched_state; + switch (state) { + case DVR_COMPLETED: return 1; + case DVR_MISSED_TIME: return 1; + default: return 0; + } +} + +static int is_dvr_entry_new(dvr_entry_t *entry) +{ + return !is_dvr_entry_old(entry); +} + +static int +extjs_dvrlist_old(http_connection_t *hc, const char *remain, void *opaque) +{ + return extjs_dvrlist(hc, remain, opaque, is_dvr_entry_old); +} + +static int +extjs_dvrlist_new(http_connection_t *hc, const char *remain, void *opaque) +{ + return extjs_dvrlist(hc, remain, opaque, is_dvr_entry_new); +} /** * @@ -1921,7 +1947,8 @@ extjs_start(void) http_path_add("/epgrelated", NULL, extjs_epgrelated, ACCESS_WEB_INTERFACE); http_path_add("/epgobject", NULL, extjs_epgobject, ACCESS_WEB_INTERFACE); http_path_add("/dvr", NULL, extjs_dvr, ACCESS_WEB_INTERFACE); - http_path_add("/dvrlist", NULL, extjs_dvrlist, ACCESS_WEB_INTERFACE); + http_path_add("/dvrlist_new", NULL, extjs_dvrlist_new, ACCESS_WEB_INTERFACE); + http_path_add("/dvrlist_old", NULL, extjs_dvrlist_old, ACCESS_WEB_INTERFACE); http_path_add("/subscriptions", NULL, extjs_subscriptions, ACCESS_WEB_INTERFACE); http_path_add("/ecglist", NULL, extjs_ecglist, ACCESS_WEB_INTERFACE); http_path_add("/config", NULL, extjs_config, ACCESS_WEB_INTERFACE); diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index 72a5ed9e..6610ad1b 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -143,7 +143,7 @@ tvheadend.dvrDetails = function(entry) { /** * */ -tvheadend.dvrschedule = function() { +tvheadend.dvrschedule = function(title, dvrStore) { var actions = new Ext.ux.grid.RowActions({ header : '', @@ -358,9 +358,9 @@ tvheadend.dvrschedule = function() { loadMask : true, stripeRows : true, disableSelection : true, - title : 'Recorder schedule', + title : title, iconCls : 'clock', - store : tvheadend.dvrStore, + store : dvrStore, cm : dvrCm, plugins : [ actions ], viewConfig : { @@ -378,7 +378,7 @@ tvheadend.dvrschedule = function() { } } ], bbar : new Ext.PagingToolbar({ - store : tvheadend.dvrStore, + store : dvrStore, pageSize : 20, displayInfo : true, displayMsg : 'Programs {0} - {1} of {2}', @@ -570,7 +570,8 @@ tvheadend.autoreceditor = function() { */ tvheadend.dvr = function() { - tvheadend.dvrStore = new Ext.data.JsonStore({ + function datastoreBuilder(url) { + return new Ext.data.JsonStore({ root : 'entries', totalProperty : 'totalCount', fields : [ { @@ -610,29 +611,47 @@ tvheadend.dvr = function() { }, { name : 'url' } ], - url : 'dvrlist', + url : url, autoLoad : true, id : 'id', remoteSort : true - }); + }); + } + tvheadend.dvrStoreNew = datastoreBuilder('dvrlist_new'); + tvheadend.dvrStoreOld = datastoreBuilder('dvrlist_old'); + + + function updateDvrStore(store, r, m) { + r.data.status = m.status; + r.data.schedstate = m.schedstate; + + store.afterEdit(r); + store.fireEvent('updated', store, r, + Ext.data.Record.COMMIT); + } tvheadend.comet.on('dvrdb', function(m) { - if (m.reload != null) tvheadend.dvrStore.reload(); + if (m.reload != null) { + tvheadend.dvrStoreOld.reload(); + tvheadend.dvrStoreNew.reload(); + } if (m.updateEntry != null) { - r = tvheadend.dvrStore.getById(m.id) - if (typeof r === 'undefined') { - tvheadend.dvrStore.reload(); + r = tvheadend.dvrStoreNew.getById(m.id); + if (typeof r !== 'undefined') { + updateDvrStore(tvheadend.dvrStoreNew, r, m); return; } - r.data.status = m.status; - r.data.schedstate = m.schedstate; - - tvheadend.dvrStore.afterEdit(r); - tvheadend.dvrStore.fireEvent('updated', tvheadend.dvrStore, r, - Ext.data.Record.COMMIT); + r = tvheadend.dvrStoreOld.getById(m.id); + if (typeof r === 'undefined') { + updateDvrStore(tvheadend.dvrStoreOld, r, m); + return; + } + + tvheadend.dvrStoreNew.reload(); + tvheadend.dvrStoreOld.reload(); } }); @@ -661,7 +680,10 @@ tvheadend.dvr = function() { autoScroll : true, title : 'Digital Video Recorder', iconCls : 'drive', - items : [ new tvheadend.dvrschedule, new tvheadend.autoreceditor ] + items : [ new tvheadend.dvrschedule('Finished recordings', tvheadend.dvrStoreOld), + new tvheadend.dvrschedule('Recorder schedule', tvheadend.dvrStoreNew), + new tvheadend.autoreceditor + ] }); return panel; }