Browse Source

Fix: article footer + improve: labeling (#4306)

* icon = open dropdown

* label icon

* added: link to edit labels

* dropdown-menu label: padding and hover

* improve input row

* CSS

* Update main.js

* Update main.js

* Update main.js

* fix

* make addItem button selectable via tabbing

* Fixed theme: Ansum

* tags menu: use the new icon

* Fixed theme: Flat design

make the manage button visible

* fixed Theme: Mapco

* Fixed theme: Pafat
maTh 4 years ago
parent
commit
c9d0d20ef6

+ 2 - 2
app/layout/aside_feed.phtml

@@ -63,8 +63,8 @@
 						<a class="dropdown-toggle"><?= _i('configure') ?></a>
 						<?php /* tag_config_template */ ?>
 					</div>
-					<?= FreshRSS_Themes::alt('label') ?> <a class="item-title" data-unread="<?= format_number($tag->nbUnread()) ?>" href="<?=
-						_url('index', $actual_view, 'get', 't_' . $tag->id()) . $state_filter_manual ?>"><?= $tag->name() ?></a>
+					<a class="item-title" data-unread="<?= format_number($tag->nbUnread()) ?>" href="<?=
+						_url('index', $actual_view, 'get', 't_' . $tag->id()) . $state_filter_manual ?>"><?= _i('label') ?> <?= $tag->name() ?></a>
 				</li>
 				<?php endforeach; ?>
 			</ul>

+ 13 - 10
app/views/helpers/index/normal/entry_bottom.phtml

@@ -40,11 +40,16 @@
 	?><li class="item">
 		<div class="dropdown dynamictags">
 			<div id="dropdown-labels-<?= $this->entry->id() ?>" class="dropdown-target"></div>
-			<?= FreshRSS_Themes::alt('label') ?>
-			<a class="dropdown-toggle" href="#dropdown-labels-<?= $this->entry->id() ?>"><?php
-				echo _t('index.menu.tags');
-			?></a>
+			<a class="dropdown-toggle" href="#dropdown-labels-<?= $this->entry->id() ?>">
+				<?= _i('label') ?><?= _t('index.menu.tags') ?>
+			</a>
 			<ul class="dropdown-menu dropdown-menu-scrollable scrollbar-thin">
+				<li class="dropdown-header">
+					<?= _t('index.menu.tags') ?>
+					<?php if (FreshRSS_Auth::hasAccess()) { ?>
+						<a href="<?= _url('tag', 'index') ?>"><?= _i('configure') ?></a>
+					<?php } ?>
+				</li>
 				<!-- Ajax -->
 			</ul>
 			<a class="dropdown-close" href="#close">❌</a>
@@ -56,10 +61,9 @@
 	?><li class="item">
 		<div class="dropdown">
 			<div id="dropdown-tags-<?= $this->entry->id() ?>" class="dropdown-target"></div>
-			<?= _i('tag') ?>
-			<a class="dropdown-toggle" href="#dropdown-tags-<?= $this->entry->id() ?>"><?php
-				echo _t('index.tag.related');
-			?></a>
+			<a class="dropdown-toggle" href="#dropdown-tags-<?= $this->entry->id() ?>">
+				<?= _i('tag') ?><?= _t('index.tag.related') ?>
+			</a>
 			<ul class="dropdown-menu">
 				<?php
 				foreach ($tags as $tag) {
@@ -75,8 +79,7 @@
 		?><div class="dropdown">
 			<div id="dropdown-share-<?= $this->entry->id() ?>" class="dropdown-target"></div>
 			<a class="dropdown-toggle" href="#dropdown-share-<?= $this->entry->id() ?>">
-				<?= _i('share') ?>
-				<?= _t('index.share') ?>
+				<?= _i('share') ?><?= _t('index.share') ?>
 			</a>
 
 			<ul class="dropdown-menu">

+ 76 - 38
p/scripts/main.js

@@ -1058,7 +1058,7 @@ function init_stream(stream) {
 
 		el = ev.target.closest('.flux_header, .flux_content');
 		if (el) {	// flux_toggle
-			if (ev.target.closest('.content, .item.website, .item.link, .dropdown-menu')) {
+			if (ev.target.closest('.content, .item.website, .item.link, .dropdown')) {
 				return true;
 			}
 			if (!context.sides_close_article && ev.target.matches('div.flux_content')) {
@@ -1067,7 +1067,7 @@ function init_stream(stream) {
 			}
 			const old_active = document.querySelector('.flux.current');
 			const new_active = el.parentNode;
-			if (ev.target.tagName.toUpperCase() === 'A') {	// Leave real links alone
+			if (ev.target.tagName.toUpperCase() === 'A') {	// Leave real links alone (but does not catch img in a link)
 				if (context.auto_mark_article) {
 					mark_read(new_active, true, false);
 				}
@@ -1128,42 +1128,44 @@ function init_stream(stream) {
 		const checkboxTag = ev.target.closest('.checkboxTag');
 		if (checkboxTag) {	// Dynamic tags
 			ev.stopPropagation();
-			const isChecked = checkboxTag.checked;
 			const tagId = checkboxTag.name.replace(/^t_/, '');
-			const tagName = checkboxTag.nextElementSibling ? checkboxTag.nextElementSibling.value : '';
-			const entry = checkboxTag.closest('div.flux');
-			const entryId = entry.id.replace(/^flux_/, '');
-			checkboxTag.disabled = true;
-
-			const req = new XMLHttpRequest();
-			req.open('POST', './?c=tag&a=tagEntry', true);
-			req.responseType = 'json';
-			req.onerror = function (e) {
-				checkboxTag.checked = !isChecked;
-				badAjax(this.status == 403);
-			};
-			req.onload = function (e) {
-				if (this.status != 200) {
-					return req.onerror(e);
-				}
-				if (entry.classList.contains('not_read')) {
-					incUnreadsTag('t_' + tagId, isChecked ? 1 : -1);
-				}
-			};
-			req.onloadend = function (e) {
-				checkboxTag.disabled = false;
-				if (tagId == 0) {
-					loadDynamicTags(checkboxTag.closest('div.dropdown'));
-				}
-			};
-			req.setRequestHeader('Content-Type', 'application/json');
-			req.send(JSON.stringify({
-				_csrf: context.csrf,
-				id_tag: tagId,
-				name_tag: tagId == 0 ? tagName : '',
-				id_entry: entryId,
-				checked: isChecked,
-			}));
+			const tagName = checkboxTag.nextElementSibling ? checkboxTag.nextElementSibling.childNodes[0].value : '';
+			if ((tagId == 0 && tagName.length > 0) || tagId != 0) {
+				const isChecked = checkboxTag.checked;
+				const entry = checkboxTag.closest('div.flux');
+				const entryId = entry.id.replace(/^flux_/, '');
+				checkboxTag.disabled = true;
+
+				const req = new XMLHttpRequest();
+				req.open('POST', './?c=tag&a=tagEntry', true);
+				req.responseType = 'json';
+				req.onerror = function (e) {
+					checkboxTag.checked = !isChecked;
+					badAjax(this.status == 403);
+				};
+				req.onload = function (e) {
+					if (this.status != 200) {
+						return req.onerror(e);
+					}
+					if (entry.classList.contains('not_read')) {
+						incUnreadsTag('t_' + tagId, isChecked ? 1 : -1);
+					}
+				};
+				req.onloadend = function (e) {
+					checkboxTag.disabled = false;
+					if (tagId == 0) {
+						loadDynamicTags(checkboxTag.closest('div.dropdown'));
+					}
+				};
+				req.setRequestHeader('Content-Type', 'application/json');
+				req.send(JSON.stringify({
+					_csrf: context.csrf,
+					id_tag: tagId,
+					name_tag: tagId == 0 ? tagName : '',
+					id_entry: entryId,
+					checked: isChecked,
+				}));
+			}
 		}
 	};
 }
@@ -1210,7 +1212,43 @@ function loadDynamicTags(div) {
 		if (!json) {
 			return req.onerror(e);
 		}
-		let html = '<li class="item"><label><input class="checkboxTag" name="t_0" type="checkbox" /> <input type="text" name="newTag" /></label></li>';
+
+		const li_item0 = document.createElement('li');
+		li_item0.setAttribute('class', 'item addItem');
+
+		const label = document.createElement('label');
+		label.setAttribute('class', 'noHover');
+
+		const input_checkboxTag = document.createElement('input');
+		input_checkboxTag.setAttribute('class', 'checkboxTag checkboxNewTag');
+		input_checkboxTag.setAttribute('name', 't_0');
+		input_checkboxTag.setAttribute('type', 'checkbox');
+
+		const input_newTag = document.createElement('input');
+		input_newTag.setAttribute('type', 'text');
+		input_newTag.setAttribute('name', 'newTag');
+		input_newTag.addEventListener('keydown', function (ev) { if (ev.key.toUpperCase() == 'ENTER') { this.parentNode.previousSibling.click(); } });
+
+		const button_btn = document.createElement('button');
+		button_btn.setAttribute('type', 'button');
+		button_btn.setAttribute('class', 'btn');
+		button_btn.addEventListener('click', function () { this.parentNode.parentNode.click(); });
+
+		const text_plus = document.createTextNode('+');
+
+		const div_stick = document.createElement('div');
+		div_stick.setAttribute('class', 'stick');
+
+		button_btn.appendChild(text_plus);
+		div_stick.appendChild(input_newTag);
+		div_stick.appendChild(button_btn);
+		label.appendChild(input_checkboxTag);
+		label.appendChild(div_stick);
+		li_item0.appendChild(label);
+
+		div.querySelector('.dropdown-menu').appendChild(li_item0);
+
+		let html = '';
 		if (json && json.length) {
 			for (let i = 0; i < json.length; i++) {
 				const tag = json[i];

+ 3 - 3
p/themes/Ansum/_components.scss

@@ -42,7 +42,7 @@
 
 	.dropdown-header {
 		// padding: 0 5px 5px;
-		margin: 1.75rem 0 0.5rem 2rem;
+		margin: 1rem 0.5rem 1rem 1rem;
 		font-weight: bold;
 		text-align: left;
 		color: variables.$grey-dark;
@@ -63,11 +63,11 @@
 			line-height: 2.5em;
 		}
 
-		&:hover {
+		&:not(.addItem):hover {
 			background: variables.$main-first;
 			color: variables.$white;
 
-			a, button {
+			a, button, label {
 				text-decoration: none;
 				color: variables.$white;
 			}

+ 18 - 0
p/themes/Ansum/_layout.scss

@@ -180,6 +180,24 @@
 	}
 }
 
+.btn {
+	border-left-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: variables.$grey-light;
+	background-position: center;
+	background-repeat: no-repeat;
+
+	@include mixins.transition(all, 0.15s, ease-in-out);
+
+	&:hover {
+		background-color: variables.$grey-medium-light;
+	}
+
+	&.active {
+		background-color: variables.$main-first;
+	}
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 19 - 4
p/themes/Ansum/ansum.css

@@ -241,7 +241,7 @@ form th {
 	right: 17px;
 }
 .dropdown-menu .dropdown-header {
-	margin: 1.75rem 0 0.5rem 2rem;
+	margin: 1rem 0.5rem 1rem 1rem;
 	font-weight: bold;
 	text-align: left;
 	color: #766556;
@@ -257,15 +257,15 @@ form th {
 	font-size: 1rem;
 	line-height: 2.5em;
 }
-.dropdown-menu .item:hover {
+.dropdown-menu .item:not(.addItem):hover {
 	background: #ca7227;
 	color: #fff;
 }
-.dropdown-menu .item:hover a, .dropdown-menu .item:hover button {
+.dropdown-menu .item:not(.addItem):hover a, .dropdown-menu .item:not(.addItem):hover button, .dropdown-menu .item:not(.addItem):hover label {
 	text-decoration: none;
 	color: #fff;
 }
-.dropdown-menu .item:hover .icon {
+.dropdown-menu .item:not(.addItem):hover .icon {
 	filter: grayscale(100%) brightness(2.5);
 }
 .dropdown-menu .item[aria-checked=true] a::before {
@@ -901,6 +901,21 @@ form th {
 	text-transform: uppercase;
 }
 
+.btn {
+	border-left-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: #f5f0ec;
+	background-position: center;
+	background-repeat: no-repeat;
+	transition: all 0.15s ease-in-out;
+}
+.btn:hover {
+	background-color: #e4d8cc;
+}
+.btn.active {
+	background-color: #ca7227;
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 19 - 4
p/themes/Ansum/ansum.rtl.css

@@ -241,7 +241,7 @@ form th {
 	left: 17px;
 }
 .dropdown-menu .dropdown-header {
-	margin: 1.75rem 2rem 0.5rem 0;
+	margin: 1rem 1rem 1rem 0.5rem;
 	font-weight: bold;
 	text-align: right;
 	color: #766556;
@@ -257,15 +257,15 @@ form th {
 	font-size: 1rem;
 	line-height: 2.5em;
 }
-.dropdown-menu .item:hover {
+.dropdown-menu .item:not(.addItem):hover {
 	background: #ca7227;
 	color: #fff;
 }
-.dropdown-menu .item:hover a, .dropdown-menu .item:hover button {
+.dropdown-menu .item:not(.addItem):hover a, .dropdown-menu .item:not(.addItem):hover button, .dropdown-menu .item:not(.addItem):hover label {
 	text-decoration: none;
 	color: #fff;
 }
-.dropdown-menu .item:hover .icon {
+.dropdown-menu .item:not(.addItem):hover .icon {
 	filter: grayscale(100%) brightness(2.5);
 }
 .dropdown-menu .item[aria-checked=true] a::before {
@@ -901,6 +901,21 @@ form th {
 	text-transform: uppercase;
 }
 
+.btn {
+	border-right-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: #f5f0ec;
+	background-position: center;
+	background-repeat: no-repeat;
+	transition: all 0.15s ease-in-out;
+}
+.btn:hover {
+	background-color: #e4d8cc;
+}
+.btn.active {
+	background-color: #ca7227;
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 1 - 1
p/themes/Flat/flat.css

@@ -768,7 +768,7 @@ a.btn {
 	padding: 5px 0;
 }
 
-#dropdown-query ~ .dropdown-menu .dropdown-header .icon {
+.dropdown-menu .dropdown-header .icon {
 	vertical-align: middle;
 	background-color: #95a5a6;
 	border-radius: 3px;

+ 1 - 1
p/themes/Flat/flat.rtl.css

@@ -768,7 +768,7 @@ a.btn {
 	padding: 5px 0;
 }
 
-#dropdown-query ~ .dropdown-menu .dropdown-header .icon {
+.dropdown-menu .dropdown-header .icon {
 	vertical-align: middle;
 	background-color: #95a5a6;
 	border-radius: 3px;

+ 3 - 3
p/themes/Mapco/_components.scss

@@ -42,7 +42,7 @@
 
 	.dropdown-header {
 		// padding: 0 5px 5px;
-		margin: 1.75rem 0 0.5rem 2rem;
+		margin: 1rem 0.5rem 1rem 1rem;
 		font-weight: bold;
 		text-align: left;
 		color: variables.$grey-dark;
@@ -62,11 +62,11 @@
 			line-height: 2.5em;
 		}
 
-		&:hover {
+		&:not(.addItem):hover {
 			background: variables.$main-first;
 			color: variables.$white;
 
-			a, button {
+			a, button, label {
 				text-decoration: none;
 				color: variables.$white;
 			}

+ 18 - 0
p/themes/Mapco/_layout.scss

@@ -183,6 +183,24 @@
 	}
 }
 
+.btn {
+	border-left-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: variables.$grey-light;
+	background-position: center;
+	background-repeat: no-repeat;
+
+	@include mixins.transition(all, 0.15s, ease-in-out);
+
+	&:hover {
+		background-color: variables.$grey-medium-light;
+	}
+
+	&.active {
+		background-color: variables.$main-first;
+	}
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 18 - 3
p/themes/Mapco/mapco.css

@@ -238,7 +238,7 @@ form th {
 	right: 18px;
 }
 .dropdown-menu .dropdown-header {
-	margin: 1.75rem 0 0.5rem 2rem;
+	margin: 1rem 0.5rem 1rem 1rem;
 	font-weight: bold;
 	text-align: left;
 	color: #5b6871;
@@ -254,11 +254,11 @@ form th {
 	font-size: 1rem;
 	line-height: 2.5em;
 }
-.dropdown-menu .item:hover {
+.dropdown-menu .item:not(.addItem):hover {
 	background: #36c;
 	color: #fff;
 }
-.dropdown-menu .item:hover a, .dropdown-menu .item:hover button {
+.dropdown-menu .item:not(.addItem):hover a, .dropdown-menu .item:not(.addItem):hover button, .dropdown-menu .item:not(.addItem):hover label {
 	text-decoration: none;
 	color: #fff;
 }
@@ -888,6 +888,21 @@ form th {
 	text-transform: uppercase;
 }
 
+.btn {
+	border-left-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: #eff0f2;
+	background-position: center;
+	background-repeat: no-repeat;
+	transition: all 0.15s ease-in-out;
+}
+.btn:hover {
+	background-color: #d5d8db;
+}
+.btn.active {
+	background-color: #36c;
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 18 - 3
p/themes/Mapco/mapco.rtl.css

@@ -238,7 +238,7 @@ form th {
 	left: 18px;
 }
 .dropdown-menu .dropdown-header {
-	margin: 1.75rem 2rem 0.5rem 0;
+	margin: 1rem 1rem 1rem 0.5rem;
 	font-weight: bold;
 	text-align: right;
 	color: #5b6871;
@@ -254,11 +254,11 @@ form th {
 	font-size: 1rem;
 	line-height: 2.5em;
 }
-.dropdown-menu .item:hover {
+.dropdown-menu .item:not(.addItem):hover {
 	background: #36c;
 	color: #fff;
 }
-.dropdown-menu .item:hover a, .dropdown-menu .item:hover button {
+.dropdown-menu .item:not(.addItem):hover a, .dropdown-menu .item:not(.addItem):hover button, .dropdown-menu .item:not(.addItem):hover label {
 	text-decoration: none;
 	color: #fff;
 }
@@ -888,6 +888,21 @@ form th {
 	text-transform: uppercase;
 }
 
+.btn {
+	border-right-width: 0;
+	padding: 0.5rem 1rem;
+	background-color: #eff0f2;
+	background-position: center;
+	background-repeat: no-repeat;
+	transition: all 0.15s ease-in-out;
+}
+.btn:hover {
+	background-color: #d5d8db;
+}
+.btn.active {
+	background-color: #36c;
+}
+
 /*=== Index menu */
 .nav_menu {
 	text-align: center;

+ 6 - 1
p/themes/Origine/origine.css

@@ -383,11 +383,16 @@ a.btn {
 }
 
 .dropdown-menu > .item > a:hover,
-.dropdown-menu > .item > button:hover {
+.dropdown-menu > .item > button:hover,
+.dropdown-menu > .item > label:hover:not(.noHover) {
 	background: #0062be;
 	color: #fff;
 }
 
+.dropdown-menu > .item > label {
+	padding: 0;
+}
+
 .dropdown-menu > .item:hover .icon {
 	filter: grayscale(100%) brightness(2.5);
 }

+ 6 - 1
p/themes/Origine/origine.rtl.css

@@ -383,11 +383,16 @@ a.btn {
 }
 
 .dropdown-menu > .item > a:hover,
-.dropdown-menu > .item > button:hover {
+.dropdown-menu > .item > button:hover,
+.dropdown-menu > .item > label:hover:not(.noHover) {
 	background: #0062be;
 	color: #fff;
 }
 
+.dropdown-menu > .item > label {
+	padding: 0;
+}
+
 .dropdown-menu > .item:hover .icon {
 	filter: grayscale(100%) brightness(2.5);
 }

+ 0 - 1
p/themes/Pafat/pafat.css

@@ -116,7 +116,6 @@ form th {
 .stick {
 	vertical-align: middle;
 	font-size: 0;
-	min-width: 215px;
 }
 
 .stick input,

+ 0 - 1
p/themes/Pafat/pafat.rtl.css

@@ -116,7 +116,6 @@ form th {
 .stick {
 	vertical-align: middle;
 	font-size: 0;
-	min-width: 215px;
 }
 
 .stick input,

+ 20 - 0
p/themes/base-theme/template.css

@@ -223,6 +223,22 @@ input[type="checkbox"] {
 	margin-right: .5em;
 }
 
+.dropdown-menu .item .checkboxNewTag {
+	display: none;
+}
+
+.dropdown-menu .item.addItem {
+	padding: 0 0.5em;
+}
+
+.dropdown-menu .item.addItem .stick {
+	width: 100%
+}
+
+.dropdown-menu .item.addItem .stick input[type=text] {
+	width: 100%;
+}
+
 button.as-link,
 button.as-link:hover,
 button.as-link:active {
@@ -1103,6 +1119,10 @@ a.website:hover .favicon {
 	list-style-type: decimal;
 }
 
+.flux_content .bottom .dropdown-toggle .icon {
+	margin-right: 5px;
+}
+
 /*=== Feed article content */
 .hide_posts > .flux:not(.active) > .flux_content {
 	display: none;

+ 20 - 0
p/themes/base-theme/template.rtl.css

@@ -223,6 +223,22 @@ input[type="checkbox"] {
 	margin-left: .5em;
 }
 
+.dropdown-menu .item .checkboxNewTag {
+	display: none;
+}
+
+.dropdown-menu .item.addItem {
+	padding: 0 0.5em;
+}
+
+.dropdown-menu .item.addItem .stick {
+	width: 100%
+}
+
+.dropdown-menu .item.addItem .stick input[type=text] {
+	width: 100%;
+}
+
 button.as-link,
 button.as-link:hover,
 button.as-link:active {
@@ -1103,6 +1119,10 @@ a.website:hover .favicon {
 	list-style-type: decimal;
 }
 
+.flux_content .bottom .dropdown-toggle .icon {
+	margin-left: 5px;
+}
+
 /*=== Feed article content */
 .hide_posts > .flux:not(.active) > .flux_content {
 	display: none;

+ 3 - 0
p/themes/icons/label.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
+  <path fill="#666" d="M4.07055 12.2189c-1.14935 0-2.0748.92544-2.0748 2.0748v29.95786c0 1.14936.92545 2.0743 2.0748 2.0743h37.31297l16.2264-15.96802c.58275-.60118.58275-1.56922 0-2.17041l-16.2264-15.96854H4.07055zM43.679 26.77252a2.5 2.5 0 0 1 2.5001 2.5001 2.5 2.5 0 0 1-2.5001 2.49959 2.5 2.5 0 0 1-2.4996-2.49959 2.5 2.5 0 0 1 2.4996-2.5001z" paint-order="markers fill stroke"/>
+</svg>