Browse Source

New: Sharing articles from the article title line (#6395)

* enable option

* Update entry_header.phtml

* frss.css

* fix print sharing

* Light refactoring

* fix

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
maTh 1 year ago
parent
commit
7aa3d9f873

+ 1 - 0
app/Controllers/configureController.php

@@ -52,6 +52,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
 			FreshRSS_Context::userConf()->content_width = Minz_Request::paramString('content_width') ?: 'thin';
 			FreshRSS_Context::userConf()->topline_read = Minz_Request::paramBoolean('topline_read');
 			FreshRSS_Context::userConf()->topline_favorite = Minz_Request::paramBoolean('topline_favorite');
+			FreshRSS_Context::userConf()->topline_sharing = Minz_Request::paramBoolean('topline_sharing');
 			FreshRSS_Context::userConf()->topline_date = Minz_Request::paramBoolean('topline_date');
 			FreshRSS_Context::userConf()->topline_link = Minz_Request::paramBoolean('topline_link');
 			FreshRSS_Context::userConf()->topline_website = Minz_Request::paramString('topline_website');

+ 1 - 0
app/Models/UserConfiguration.php

@@ -61,6 +61,7 @@ declare(strict_types=1);
  * @property bool $topline_date
  * @property bool $topline_display_authors
  * @property bool $topline_favorite
+ * @property bool $topline_sharing
  * @property bool $topline_link
  * @property bool $topline_read
  * @property bool $topline_summary

+ 3 - 1
app/views/configure/display.phtml

@@ -212,7 +212,9 @@
 								data-leave-validation="<?= FreshRSS_Context::userConf()->topline_favorite ?>" /></td>
 							<td><input type="checkbox" disabled="disabled" /></td>
 							<td><input type="checkbox" disabled="disabled" /></td>
-							<td><input type="checkbox" disabled="disabled" /></td>
+							<td><input type="checkbox" name="topline_sharing" value="1"<?=
+								FreshRSS_Context::userConf()->topline_sharing ? ' checked="checked"' : '' ?>
+								data-leave-validation="<?= FreshRSS_Context::userConf()->topline_sharing ?>" /></td>
 							<td><input type="checkbox" name="topline_summary" value="1"<?=
 								FreshRSS_Context::userConf()->topline_summary ? 'checked="checked"' : '' ?>
 								data-leave-validation="<?= FreshRSS_Context::userConf()->topline_summary ?>" /></td>

+ 1 - 33
app/views/helpers/index/normal/entry_bottom.phtml

@@ -76,39 +76,7 @@
 			<a class="dropdown-toggle" href="#dropdown-share-<?= $this->entry->id() ?>">
 				<?= _i('share') ?><?= _t('index.share') ?>
 			</a>
-
-			<ul class="dropdown-menu">
-				<li class="dropdown-header"><?= _t('index.share') ?> <a href="<?= _url('configure', 'integration') ?>"><?= _i('configure') ?></a></li><?php
-					$id = $this->entry->id();
-					$link = $this->entry->link();
-					$title = $this->entry->title() . ' · ' . ($this->feed === null ? '' : $this->feed->name());
-					foreach (FreshRSS_Context::userConf()->sharing as $share_options) {
-						$share = FreshRSS_Share::get($share_options['type']);
-						if ($share === null) {
-							continue;
-						}
-						$cssClass = $share->isDeprecated() ? ' error' : '';
-						$share_options['id'] = $id;
-						$share_options['link'] = $link;
-						$share_options['title'] = $title;
-						$share->update($share_options);
-				?><li class="item share<?= $cssClass ?>">
-					<?php if ('GET' === $share->method()) {
-						if ($share->HTMLtag() !== 'button') {?>
-						<a target="_blank" rel="noreferrer" href="<?= $share->url() ?>" data-type="<?= $share->type() ?>"><?= $share->name() ?></a>
-						<?php } else { ?>
-						<button type="button" class="as-link" data-url="<?= $share->url() ?>" data-type="<?= $share->type() ?>" data-title="<?= htmlspecialchars($title) ?>"><?= $share->name() ?></button>
-						<?php
-						}
-					} else {?>
-						<a href="POST"><?= $share->name() ?></a>
-						<form method="POST" action="<?= $share->url() ?>" disabled="disabled">
-							<input type="hidden" value="<?= $link ?>" name="<?= $share->field() ?>"/>
-						</form>
-					<?php } ?>
-				</li><?php
-					}
-			?></ul>
+			<?php $this->renderHelper('index/normal/entry_share_menu'); ?>
 			<a class="dropdown-close" href="#close">❌</a>
 		</div>
 		<?php } ?>

+ 13 - 0
app/views/helpers/index/normal/entry_header.phtml

@@ -3,6 +3,7 @@
 	/** @var FreshRSS_View $this */
 	$topline_read = FreshRSS_Context::userConf()->topline_read;
 	$topline_favorite = FreshRSS_Context::userConf()->topline_favorite;
+	$topline_sharing = FreshRSS_Context::userConf()->topline_sharing;
 	$topline_website = FreshRSS_Context::userConf()->topline_website;
 	$topline_thumbnail = FreshRSS_Context::userConf()->topline_thumbnail;
 	$topline_summary = FreshRSS_Context::userConf()->topline_summary;
@@ -72,6 +73,18 @@
 	endif; ?>
 	<?php if ($topline_date) { ?><span class="item-element date"><time datetime="<?= $this->entry->machineReadableDate() ?>"><?= $this->entry->date() ?></time>&nbsp;</span><?php } ?>
 	</li>
+	<?php if ($topline_sharing) { ?>
+		<li class="item share">
+			<div class="item-element dropdown">
+				<div id="dropdown-share2-<?= $this->entry->id() ?>" class="dropdown-target"></div>
+				<a class="dropdown-toggle" href="#dropdown-share2-<?= $this->entry->id() ?>" title="<?= _t('index.share') ?>">
+					<?= _i('share') ?>
+				</a>
+				<?php $this->renderHelper('index/normal/entry_share_menu'); ?>
+				<a class="dropdown-close" href="#close">❌</a>
+			</div>
+		</li>
+	<?php } ?>
 	<?php if ($topline_link) { ?><li class="item link"><a target="_blank" rel="noreferrer" href="<?= $this->entry->link() ?>" class="item-element" title="<?=
 		_t('conf.shortcut.see_on_website') ?>"><?= _i('link') ?></a></li><?php } ?>
 </ul>

+ 37 - 0
app/views/helpers/index/normal/entry_share_menu.phtml

@@ -0,0 +1,37 @@
+<?php
+	declare(strict_types=1);
+	/** @var FreshRSS_View $this */
+	//TODO: To reduce output size, replace by an on-demand JavaScript menu, potentially using HTML template element
+?>
+<ul class="dropdown-menu">
+	<li class="dropdown-header"><?= _t('index.share') ?> <a href="<?= _url('configure', 'integration') ?>"><?= _i('configure') ?></a></li><?php
+		$id = $this->entry->id();
+		$link = $this->entry->link();
+		$title = $this->entry->title() . ' · ' . ($this->feed === null ? '' : $this->feed->name());
+		foreach (FreshRSS_Context::userConf()->sharing as $share_options) {
+			$share = FreshRSS_Share::get($share_options['type']);
+			if ($share === null) {
+				continue;
+			}
+			$cssClass = $share->isDeprecated() ? ' error' : '';
+			$share_options['id'] = $id;
+			$share_options['link'] = $link;
+			$share_options['title'] = $title;
+			$share->update($share_options);
+			?><li class="item share<?= $cssClass ?>">
+				<?php if ('GET' === $share->method()) {
+					if ($share->HTMLtag() !== 'button') {?>
+					<a target="_blank" rel="noreferrer" href="<?= $share->url() ?>" data-type="<?= $share->type() ?>"><?= $share->name() ?></a>
+					<?php } else { ?>
+					<button type="button" class="as-link" data-url="<?= $share->url() ?>" data-type="<?= $share->type() ?>" data-title="<?= htmlspecialchars($title) ?>"><?= $share->name() ?></button>
+					<?php
+					}
+				} else {?>
+					<a href="POST"><?= $share->name() ?></a>
+					<form method="POST" action="<?= $share->url() ?>" disabled="disabled">
+						<input type="hidden" value="<?= $link ?>" name="<?= $share->field() ?>"/>
+					</form>
+				<?php } ?>
+			</li><?php
+		}
+?></ul>

+ 1 - 0
config-user.default.php

@@ -102,6 +102,7 @@ return array (
 
 	'topline_read' => true,
 	'topline_favorite' => true,
+	'topline_sharing' => false,
 	'topline_website' => 'full',
 	'topline_thumbnail' => 'none',
 	'topline_summary' => false,

+ 18 - 5
p/scripts/main.js

@@ -402,6 +402,13 @@ function mark_favorite(div) {
 const freshrssOpenArticleEvent = document.createEvent('Event');
 freshrssOpenArticleEvent.initEvent('freshrss:openArticle', true, true);
 
+function loadLazyImages(rootElement) {
+	rootElement.querySelectorAll('img[data-original], iframe[data-original]').forEach(function (el) {
+		el.src = el.getAttribute('data-original');
+		el.removeAttribute('data-original');
+	});
+}
+
 function toggleContent(new_active, old_active, skipping) {
 	// If skipping, move current without activating or marking as read
 	if (!new_active) {
@@ -409,10 +416,7 @@ function toggleContent(new_active, old_active, skipping) {
 	}
 
 	if (context.does_lazyload && !skipping) {
-		new_active.querySelectorAll('img[data-original], iframe[data-original]').forEach(function (el) {
-			el.src = el.getAttribute('data-original');
-			el.removeAttribute('data-original');
-		});
+		loadLazyImages(new_active);
 	}
 
 	if (old_active !== new_active) {
@@ -1101,7 +1105,16 @@ function init_stream(stream) {
 			for (let i = 0; i < document.styleSheets.length; i++) {
 				tmp_window.document.writeln('<link href="' + document.styleSheets[i].href + '" rel="stylesheet" type="text/css" />');
 			}
-			tmp_window.document.writeln(el.closest('.flux_content').querySelector('.content').innerHTML);
+			const flux_content = el.closest('.flux_content');
+			let content_el = null;
+			if (flux_content) {
+				content_el = el.closest('.flux_content').querySelector('.content');
+			}
+			if (content_el === null) {
+				content_el = el.closest('.flux').querySelector('.flux_content .content');
+			}
+			loadLazyImages(content_el);
+			tmp_window.document.writeln(content_el.innerHTML);
 			tmp_window.document.close();
 			tmp_window.focus();
 			tmp_window.print();

+ 2 - 0
p/themes/base-theme/frss.css

@@ -1257,12 +1257,14 @@ input[type="search"] {
 
 .flux .flux_header .item.manage .item-element,
 .flux .flux_header .item.website .item-element,
+.flux .flux_header .item.share .dropdown-toggle,
 .flux .flux_header .item.link .item-element {
 	padding-left: var(--frss-padding-flux-items);
 	padding-right: var(--frss-padding-flux-items);
 }
 
 .flux .item.manage,
+.flux .flux_header > .item.share,
 .flux .item.link {
 	width: calc(1rem + 2 * var(--frss-padding-flux-items));
 }

+ 2 - 0
p/themes/base-theme/frss.rtl.css

@@ -1257,12 +1257,14 @@ input[type="search"] {
 
 .flux .flux_header .item.manage .item-element,
 .flux .flux_header .item.website .item-element,
+.flux .flux_header .item.share .dropdown-toggle,
 .flux .flux_header .item.link .item-element {
 	padding-right: var(--frss-padding-flux-items);
 	padding-left: var(--frss-padding-flux-items);
 }
 
 .flux .item.manage,
+.flux .flux_header > .item.share,
 .flux .item.link {
 	width: calc(1rem + 2 * var(--frss-padding-flux-items));
 }