Commit 89ef19b0 authored by yPhil's avatar yPhil
Browse files

Merge branch 'server' : #v1.5.7b

parents 3996db45 bdeb9b60
Pipeline #495805 passed with stage
in 20 seconds
......@@ -30,8 +30,8 @@ Pétrolette is fully self-contained, makes **no external call** whatsoever, and
- Displays all modern feeds (Atom, RSS 1/2, **MediaRSS**, etc.)
- New items indicator / badge
- **Video / Audio playing** directly in Pétrolette
- **Discovery of the feed** in a page / website
- Mobile / **phone** / tablet / responsive interface
- **Discovery of all the feeds** in a website / URL
- Mobile / **phone** / tablet / **Big TV** responsive interface
- Direct link to all the article / item's resources (image, video, sound)
- **Search** within all the feeds
- Advanced image management (download, gallery, slideshow, etc.)
......
{
"name": "petrolette",
"description": "The news page that doesn't know you",
"version": "v1.5.6",
"version": "1.5.6",
"private": true,
"license": "GPL-3.0-only",
"HTTP_PORT": 8000,
......
......@@ -1525,6 +1525,7 @@ select#gallerySlideTransition {
.ui-progressbar {
position: relative;
background: var(--color-button-bg);
border: var(--color-button-bg-active) !important;
}
a:visited.ui-button {
......
......@@ -708,16 +708,12 @@ PTL.dialog = {
$dialog.dialog('open');
});
},
killTab: function($button) {
killTab: function($button, tabName, $selectedTab, $selectedPanel, numberOfFeeds) {
$('div#ptlDialogs').load('/static/templates/dialogs.html #questionDialog', function() {
const $dialog = $(this),
$tabs = $('#tabs'),
$a = $button.prev('a.ui-tabs-anchor'),
tabId = $a.attr('href'),
$selectedTab = $a.parent(),
$selectedPanel = $tabs.find(tabId),
$icon = $dialog.find('div#icon > i'),
selectedTabIndex = $tabs.tabs('option', 'active'),
previousTabIndex = selectedTabIndex === 0 ? 0 : selectedTabIndex - 1;
......@@ -765,10 +761,9 @@ PTL.dialog = {
.addClass('dangerous')
.text(PTL.tr('This action cannot be undone.'))
.next('h2').text(PTL.tr('Name'))
.next('p').text($a.text())
.next('p').text(tabName)
.next('h2').text(PTL.tr('Number of feeds'))
.next('p').text($selectedPanel.find('li.feed').length);
.next('p').text(numberOfFeeds);
}
});
......
......@@ -342,17 +342,17 @@ PTL.feed = {
if (!videoUrl && !audioUrl && imageUrl && typeof imageUrl !== 'undefined' && !imageUrl.includes('pixel')) {
$imageLink
.attr('href', imageUrl)
.attr('title', $summary.trim())
.attr('data-fancybox', 'gallery')
.attr('data-caption', '<a href="' + item.link + '" class="ui-button ui-corner-all" title="' + $summary.trim() + '">' + item.title + '</a>');
const protocols = ['https://', 'http://', '//'];
let isAbsolute = protocols.some(p => imageUrl.startsWith(p));
if (!isAbsolute) imageUrl = feedHost + '/' + imageUrl;
$imageLink
.attr('href', imageUrl)
.attr('title', $summary.trim())
.attr('data-fancybox', 'gallery')
.attr('data-caption', '<a href="' + item.link + '" class="ui-button ui-corner-all" title="' + $summary.trim() + '">' + item.title + '</a>');
$image = $('<img>')
.attr('src', '/static/images/loading.gif')
......@@ -577,32 +577,18 @@ PTL.feed = {
$refreshButton.addClass('spin');
let fetchFeed = await PTL.feed.fetchFeed(feedUrl, feedLastItem);
if (fetchFeed.error) {
try {
let fetchFeed = await PTL.feed.fetchFeed(feedUrl, feedLastItem);
$feedBody
.empty()
.append(PTL.feed.errorFeed(fetchFeed.error, feedUrl))
.css('height', '');
$feedLink.addClass('danger');
$refreshButton.removeClass('spin');
if (fetchFeed.error) {
} else {
let lastItems = await PTL.feed.lastItems(fetchFeed.feedItems, $dataStore);
let isInsecureLinks = lastItems[2];
const feedName = fetchFeed.feedTitle;
let $insecureIcon = $('<i>')
.attr('class', 'icon-lock warning')
.attr('title', PTL.tr("Some linked elements (image, audio or video) within this feed's items could not be loaded because they were served insecurely"));
if (isInsecureLinks) $warningIconSpan.html($insecureIcon);
$feedBody.html(lastItems[0]);
$feedBody
.empty()
.append(PTL.feed.errorFeed(fetchFeed.error, feedUrl))
.css('height', '');
$feedLink.addClass('danger');
$refreshButton.removeClass('spin');
$refreshButton
.attr('title', PTL.tr('Refresh this feed') + ' (' + feedUrl + ', ' + timeStamp + ')')
......@@ -626,8 +612,56 @@ PTL.feed = {
$badge.fadeOut('slow');
}
}
let lastItems = await PTL.feed.lastItems(fetchFeed.feedItems, $dataStore);
let isInsecureLinks = lastItems[2];
const feedName = fetchFeed.feedTitle;
let $insecureIcon = $('<i>')
.attr('class', 'icon-lock-open insecureIcon warning')
.attr('title', PTL.tr("Some linked elements (image, audio or video) within this feed's items could not be loaded because they were served insecurely"));
if (isInsecureLinks) $warningIconSpan.html($insecureIcon);
$feedBody.html(lastItems[0]);
$refreshButton
.attr('title', PTL.tr('Refresh this feed') + ' (' + feedUrl + ', ' + timeStamp + ')')
.removeClass('spin');
$feedLink
.attr('href', fetchFeed.feedLink)
.attr('title', feedName)
.text(feedName);
if ($dataStore.data('name') == '') $dataStore.data('name', feedName);
if (fetchFeed.totalNewItems > 0) {
$dataStore.data('lastitem', fetchFeed.lastItem);
PTL.tab.saveTabs(true);
$badge
.text(fetchFeed.totalNewItems)
.attr('title', PTL.tr('There are %1 new items in this feed', fetchFeed.totalNewItems))
.fadeIn('slow');
} else {
$badge.fadeOut('slow');
}
}
} catch (error) {
console.error('WOA: %s (%o)', feedUrl, error);
$feedBody
.empty()
.append(PTL.feed.errorFeed(fetchFeed.error, feedUrl))
.css('height', '');
$feedLink.addClass('danger');
$refreshButton.removeClass('spin');
}
} else {
$feedBody.addClass('folded');
......
This diff is collapsed.
......@@ -80,13 +80,13 @@ var PTL = (function() {
$searchPrefixOkButton.click(function(){
const clean = DOMPurify.sanitize($searchPrefixInput.val());
PTL.prefs.writeConfig('searchPrefix', clean);
PTL.prefs.writeConfig('searchPrefix', clean, true);
PTL.util.say(PTL.tr('Search prefix') + ': ' + clean, 'success', true);
});
$('button#nagOk').click(function(){
$('div#nagBar').hide('fade', 150);
PTL.prefs.writeConfig('nagBarOk', true);
PTL.prefs.writeConfig('nagBarOk', true, true);
});
$('#logoTitle > .logoTitle').click(function(){
......@@ -282,7 +282,7 @@ var PTL = (function() {
$langMenu.change(function() {
var selectedLang = $(this).val();
PTL.language = selectedLang;
PTL.prefs.writeConfig('lang', selectedLang);
PTL.prefs.writeConfig('lang', selectedLang, true);
PTL.prefs.writeConfig('userSetLang', true);
PTL.util.translate();
});
......@@ -391,7 +391,7 @@ var PTL = (function() {
$sideMenu.find('.mediaPreloadSwitcher').checkboxradio('refresh');
$('.mediaPreloadSwitcher').change(function() {
PTL.prefs.writeConfig('mediaPreload', $(this).attr('value'));
PTL.prefs.writeConfig('mediaPreload', $(this).attr('value'), true);
});
var gallerySlideshowSpeed = PTL.prefs.readConfig('gallerySlideshowSpeed');
......@@ -414,7 +414,7 @@ var PTL = (function() {
$sideMenu.find('select#gallerySlideTransition').change(function() {
$.fancybox.defaults.transitionEffect = $(this).val();
PTL.prefs.writeConfig('gallerySlideTransition', $(this).val());
PTL.prefs.writeConfig('gallerySlideTransition', $(this).val(), true);
});
$sideMenu.find('select#gallerySlideTransition').val(gallerySlideTransition);
......@@ -465,7 +465,7 @@ var PTL = (function() {
$(this).find('.ui-slider-handle').text(PTL.util.milliToSecs(parseInt(ui.value)) + 's');
},
change: function(event, ui) {
PTL.prefs.writeConfig('gallerySlideshowSpeed', ui.value);
PTL.prefs.writeConfig('gallerySlideshowSpeed', ui.value, true);
$('#tabs').find("[data-fancybox]").fancybox({
slideShow: {
speed: ui.value
......
......@@ -2,79 +2,81 @@
PTL.prefs = {
getDefaultFeeds: function() {
var result = null;
$.ajax({
url: '/static/js/default-feeds.json',
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
result = data;
}
});
return result;
},
readConfig: function(key) {
const defaults = {
'gallerySlideTransition': 'fade',
'gallerySlideshowSpeed': 3000,
'lang': 'en',
'userSetLang': false,
'nagBarOk': false,
'searchPrefix': 'https://searx.prvcy.eu/search?categories=general&time_range=week&language=en&format=rss&q=',
'searchPrefixDefault': 'https://searx.prvcy.eu/search?categories=general&time_range=week&language=en&format=rss&q=',
'tabDropActivate': true,
'brokenImages': 'hide',
'mediaPreload': 'metadata',
'theme': 'night',
'nextNag': 0,
'writeTime': Date.now()
};
if (typeof localStorage.getItem(key) === 'undefined' || !localStorage.getItem(key)) {
if (key === 'feeds') {
return JSON.stringify(PTL.prefs.getDefaultFeeds());
} else {
return defaults[key];
}
} else {
return localStorage.getItem(key);
}
},
writeConfig: function(key, val) {
$('div#logoTitle i').addClass('writing');
if (key === 'feeds') {
localStorage.setItem('writeTime', Date.now());
}
localStorage.setItem(key, val);
setTimeout(function() {
$('div#logoTitle i').delay('slow').removeClass('writing');
}, 300);
},
exportConfig: function(data, fileName) {
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
const json = JSON.stringify(data, null, 2),
blob = new Blob([json], { type: "application/json" }),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
getDefaultFeeds: function() {
var result = null;
$.ajax({
url: '/static/js/default-feeds.json',
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
result = data;
}
});
return result;
},
readConfig: function(key) {
const defaults = {
'gallerySlideTransition': 'fade',
'gallerySlideshowSpeed': 3000,
'lang': 'en',
'userSetLang': false,
'nagBarOk': false,
'searchPrefix': 'https://searx.prvcy.eu/search?categories=general&time_range=week&language=en&format=rss&q=',
'searchPrefixDefault': 'https://searx.prvcy.eu/search?categories=general&time_range=week&language=en&format=rss&q=',
'tabDropActivate': true,
'brokenImages': 'hide',
'mediaPreload': 'metadata',
'theme': 'night',
'nextNag': 0,
'writeTime': Date.now()
};
if (typeof localStorage.getItem(key) === 'undefined' || !localStorage.getItem(key)) {
if (key === 'feeds') {
return JSON.stringify(PTL.prefs.getDefaultFeeds());
} else {
return defaults[key];
}
} else {
return localStorage.getItem(key);
}
},
writeConfig: function(key, val, isEchoedToConsole) {
if (key === 'feeds') {
localStorage.setItem('writeTime', Date.now());
}
localStorage.setItem(key, val);
$('div#logoTitle i').addClass('writing');
setTimeout(function() {
$('div#logoTitle i').delay('slow').removeClass('writing');
}, 300);
if (isEchoedToConsole) PTL.util.say(PTL.tr('Preferences saved'), 'success');
},
exportConfig: function(data, fileName) {
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
const json = JSON.stringify(data, null, 2),
blob = new Blob([json], { type: "application/json" }),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
};
......@@ -34,7 +34,23 @@ PTL.tab = {
});
$tabs.on("click", "i.tabCloser", function() {
PTL.dialog.killTab($(this));
const $tabs = $('#tabs'),
$a = $(this).prev('a.ui-tabs-anchor'),
tabName = $a.text(),
tabId = $a.attr('href'),
$selectedTab = $a.parent(),
$selectedPanel = $tabs.find(tabId),
numberOfFeeds = $selectedPanel.find('li.feed').length;
if (numberOfFeeds) {
PTL.dialog.killTab($(this), $a.text(), $selectedTab, $selectedPanel, numberOfFeeds);
} else {
$selectedTab.remove();
$selectedPanel.remove();
PTL.tab.saveTabs();
}
});
if (PTL.util.isMobile()) {
......@@ -144,7 +160,7 @@ PTL.tab = {
PTL.util.say(PTL.tr('Pétrolette init finished'), 'success');
PTL.tab.saveTabs();
PTL.tab.saveTabs(true);
},
empty: function(callback) {
......
......@@ -157,7 +157,6 @@ PTL.util = {
},
isUrl: function(u) {
// return new RegExp('^(?:[a-z]+:)?//', 'i').test(u);
try {
new Url.URL(u);
......
......@@ -48,7 +48,7 @@
{
"url": "https://feeds.arstechnica.com/arstechnica/index",
"name": "Ars Technica",
"type": "text",
"type": "mixed",
"limit": 452,
"status": "on",
"iconhash": "909ebf2b292548840863bf882fe33f5b",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment