diff options
| author | 2018-09-29 20:47:17 +0200 | |
|---|---|---|
| committer | 2018-09-29 20:47:17 +0200 | |
| commit | 8ee8a573f1f7e9cc45f9b3c46627d15670f14f3a (patch) | |
| tree | 14200758ab43e4031f60b46b8c6e9018b43e53af /p/scripts | |
| parent | 3ae1b57c9d2e23157be54e8fe9865b85872ff9e7 (diff) | |
Custom labels (#2027)
* First draft of custom tags
https://github.com/FreshRSS/FreshRSS/issues/928
https://github.com/FreshRSS/FreshRSS/issues/1367
* SMALLINT to BIGINT for id_entry
And uppercase SQL types
* Fix layout for unreads
* Start UI menu
* Change menu order
* Clean database helpers
https://github.com/FreshRSS/FreshRSS/pull/2027#discussion_r217971535
* Travis rules do not understand PostgreSQL constants
Grrr
* Tag controller + UI
* Add column attributes to tags
* Use only favicon for now, for label
* Fix styling for different themes
* Constant for maximum InnoDB index length in Unicode
https://github.com/FreshRSS/FreshRSS/pull/2027#discussion_r219052200
(I would have personnally prefered keeping the readability of a real
value instead of a constant, in this case of many SQL fields)
* Use FreshRSS_Factory::createCategoryDao
* Add view of all articles containing any tag
* Fix search in tags
* Mark as read tags
* Partial auto-update unread tags
* More auto update tag unreads
* Add tag deletion
* Do not purge tagged articles
* Minor comment
* Fix SQLite and UI bug
* Google Reader API support for user tags
Add SQL check that tag names must be distinct from category names
* whitespace
* Add missing API for EasyRSS
* Compatibility SQLite
Problematic parentheses
* Add SQL DISTINCT for cases with multiple tags
* Fix for PostgreSQL
PostgreSQL needs some additional type hint to avoid "could not determine
data type of parameter $1"
http://www.postgresql-archive.org/Could-not-determine-data-type-of-parameter-1-tp2171092p2171094.html
Diffstat (limited to 'p/scripts')
| -rw-r--r-- | p/scripts/main.js | 108 |
1 files changed, 102 insertions, 6 deletions
diff --git a/p/scripts/main.js b/p/scripts/main.js index 6ab256065..cac2e8706 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -114,6 +114,17 @@ function incUnreadsFeed(article, feed_id, nb) { return isCurrentView; } +function incUnreadsTag(tag_id, nb) { + var $t = $('#t_' + tag_id); + var unreads = str2int($t.attr('data-unread')); + $t.attr('data-unread', unreads + nb) + .children('.item-title').attr('data-unread', numberFormat(unreads + nb)); + + $t = $('.category.tags').find('.title'); + unreads = str2int($t.attr('data-unread')); + $t.attr('data-unread', numberFormat(unreads + nb)); +} + var pending_entries = {}; function mark_read(active, only_not_read) { if ((active.length === 0) || (!active.attr('id')) || @@ -157,6 +168,12 @@ function mark_read(active, only_not_read) { } faviconNbUnread(); + if (data.tags) { + for (var i = data.tags.length - 1; i >= 0; i--) { + incUnreadsTag(data.tags[i], inc); + } + } + delete pending_entries[active.attr('id')]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); @@ -529,12 +546,16 @@ function init_column_categories() { $(this).parent().next(".tree-folder-items").slideToggle(300 , function() { $(document.body).trigger("sticky_kit:recalc"); }); return false; }); - $('#aside_feed').on('click', '.tree-folder-items .item .dropdown-toggle', function () { + $('#aside_feed').on('click', '.tree-folder-items .feed .dropdown-toggle', function () { if ($(this).nextAll('.dropdown-menu').length === 0) { - var feed_id = $(this).closest('.item').attr('id').substr(2), + var itemId = $(this).closest('.item').attr('id'), + templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template', + id = itemId.substr(2), feed_web = $(this).data('fweb'), - template = $('#feed_config_template').html().replace(/------/g, feed_id).replace('http://example.net/', feed_web); - $(this).attr('href', '#dropdown-' + feed_id).prev('.dropdown-target').attr('id', 'dropdown-' + feed_id).parent().append(template); + template = $('#' + templateId) + .html().replace(/------/g, id).replace('http://example.net/', feed_web); + $(this).attr('href', '#dropdown-' + id).prev('.dropdown-target').attr('id', 'dropdown-' + id).parent() + .append(template).find('button.confirm').removeAttr('disabled'); $('.tree-folder-items .dropdown-close a').click(function(){ $('.tree').removeClass('treepadding'); $(document.body).trigger("sticky_kit:recalc"); @@ -606,7 +627,7 @@ function init_shortcuts() { auto_share(String.fromCharCode(evt.keyCode)); } } - for(var i = 1; i < 10; i++) { + for (var i = 1; i < 10; i++) { shortcut.add(i.toString(), addShortcut, { 'disable_in_input': true }); @@ -830,6 +851,69 @@ function init_nav_entries() { }); } +function loadDynamicTags($div) { + $div.removeClass('dynamictags'); + $div.find('li.item').remove(); + var entryId = $div.closest('div.flux').attr('id').replace(/^flux_/, ''); + $.getJSON('./?c=tag&a=getTagsForEntry&id_entry=' + entryId) + .done(function (data) { + var $ul = $div.find('.dropdown-menu'); + $ul.append('<li class="item"><label><input class="checkboxTag" name="t_0" type="checkbox" /> <input type="text" name="newTag" /></label></li>'); + if (data && data.length) { + for (var i = 0; i < data.length; i++) { + var tag = data[i]; + $ul.append('<li class="item"><label><input class="checkboxTag" name="t_' + tag.id + '" type="checkbox"' + + (tag.checked ? ' checked="checked"' : '') + '> ' + tag.name + '</label></li>'); + } + } + }) + .fail(function () { + $div.find('li.item').remove(); + $div.addClass('dynamictags'); + }); +} + +function init_dynamic_tags() { + $stream.on('click', '.dynamictags', function () { + loadDynamicTags($(this)); + }); + + $stream.on('change', '.checkboxTag', function (ev) { + var $checkbox = $(this); + $checkbox.prop('disabled', true); + var isChecked = $checkbox.prop('checked'); + var tagId = $checkbox.attr('name').replace(/^t_/, ''); + var tagName = $checkbox.siblings('input[name]').val(); + var $entry = $checkbox.closest('div.flux'); + var entryId = $entry.attr('id').replace(/^flux_/, ''); + $.ajax({ + type: 'POST', + url: './?c=tag&a=tagEntry', + data: { + _csrf: context.csrf, + id_tag: tagId, + name_tag: tagId == 0 ? tagName : '', + id_entry: entryId, + checked: isChecked, + }, + }) + .done(function () { + if ($entry.hasClass('not_read')) { + incUnreadsTag(tagId, isChecked ? 1 : -1); + } + }) + .fail(function () { + $checkbox.prop('checked', !isChecked); + }) + .always(function () { + $checkbox.prop('disabled', false); + if (tagId == 0) { + loadDynamicTags($checkbox.closest('div.dropdown')); + } + }); + }); +} + // <actualize> var feed_processed = 0; @@ -1004,7 +1088,7 @@ function refreshUnreads() { var isAll = $('.category.all.active').length > 0, new_articles = false; - $.each(data, function(feed_id, nbUnreads) { + $.each(data.feeds, function(feed_id, nbUnreads) { feed_id = 'f_' + feed_id; var elem = $('#' + feed_id).get(0), feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; @@ -1016,6 +1100,17 @@ function refreshUnreads() { } }); + var nbUnreadTags = 0; + + $.each(data.tags, function(tag_id, nbUnreads) { + nbUnreadTags += nbUnreads; + $('#t_' + tag_id).attr('data-unread', nbUnreads) + .children('.item-title').attr('data-unread', numberFormat(nbUnreads)); + }); + + $('.category.tags').attr('data-unread', nbUnreadTags) + .find('.title').attr('data-unread', numberFormat(nbUnreadTags)); + var nb_unreads = str2int($('.category.all .title').attr('data-unread')); if (nb_unreads > 0 && new_articles) { @@ -1432,6 +1527,7 @@ function init_afterDOM() { init_load_more($stream); init_posts(); init_nav_entries(); + init_dynamic_tags(); init_print_action(); init_post_action(); init_notifs_html5(); |
