فهرست منبع

Improve theme slider (#8152)

Ref https://github.com/FreshRSS/FreshRSS/pull/8149
Ref https://github.com/FreshRSS/FreshRSS/issues/6577

Before
<img width="969" height="582" alt="grafik" src="https://github.com/user-attachments/assets/5e1e5e9a-31de-4327-a639-6327d602cf8a" />

After
Buttons as navigation elements. Not it is crystal clear that the themes can be changed.
The theme counter is a bit more prominent to show the big amount of shipped themes.
<img width="1041" height="575" alt="grafik" src="https://github.com/user-attachments/assets/b498e74f-1284-40ad-b871-41ce238a49ff" />
maTh 5 ماه پیش
والد
کامیت
53c1562cc0

+ 57 - 54
app/views/configure/display.phtml

@@ -43,64 +43,67 @@
 		<div class="form-group">
 			<label class="group-name" for="theme"><?= _t('conf.display.theme') ?></label>
 			<div class="group-controls">
-				<ul class="theme-preview-list">
-					<?php $slides = count($this->themes); $i = 1; $themeAvailable = false; ?>
-					<?php
-						foreach ($this->themes as $theme) { ?>
-						<?php if (FreshRSS_Context::userConf()->theme === $theme['id']) {
-							$checked = 'checked="checked"';
-							$themeAvailable = true;
-						} else {
-							$checked = '';
-						} ?>
-						<input type="radio" name="theme" id="img-<?= $i ?>" <?= $checked ?> value="<?= $theme['id'] ?>" />
-						<li class="preview-container">
-							<div class="preview">
-								<img src="<?= Minz_Url::display('/themes/' . $theme['id'] . '/thumbs/original.png') ?>" loading="lazy" />
-							</div>
-							<div class="nav">
-								<?php if ($i !== 1) {?>
-									<label for="img-<?= $i - 1 ?>" class="prev">‹</label>
-								<?php } ?>
-								<?php if ($i !== $slides) {?>
-									<label for="img-<?= $i + 1 ?>" class="next">›</label>
-								<?php } ?>
-							</div>
-							<div class="properties">
-								<div>
-									<?php if (!empty($theme['deprecated'])) { ?>
-										<span class="deprecated error"><?= _t('conf.display.theme.deprecated') ?>:</span>
+				<div class="theme-preview-list-wrapper">
+					<ul class="theme-preview-list">
+						<?php $slides = count($this->themes); $i = 1; $themeAvailable = false; ?>
+						<?php
+							foreach ($this->themes as $theme) { ?>
+							<?php if (FreshRSS_Context::userConf()->theme === $theme['id']) {
+								$checked = 'checked="checked"';
+								$themeAvailable = true;
+							} else {
+								$checked = '';
+							} ?>
+							<input type="radio" name="theme" id="img-<?= $i ?>" <?= $checked ?> value="<?= $theme['id'] ?>" />
+							<li class="preview-container">
+								<div class="preview">
+									<img src="<?= Minz_Url::display('/themes/' . $theme['id'] . '/thumbs/original.png') ?>" loading="lazy" />
+								</div>
+								<div class="nav">
+									<?php if ($i !== 1) {?>
+										<label for="img-<?= $i - 1 ?>" class="btn prev"><?= _i('prev') ?></label>
+									<?php } ?>
+									<?php if ($i !== $slides) {?>
+										<label for="img-<?= $i + 1 ?>" class="btn next"><?= _i('next') ?></label>
 									<?php } ?>
-									<?= sprintf('%s — %s %s', $theme['name'], _t('gen.short.by_author'), $theme['author']) ?>
 								</div>
-								<div>
-									<?php if (!empty($theme['deprecated'])) { ?>
-										<span class="deprecated"><?= _t('conf.display.theme.deprecated.description') ?></span><br />
+								<div class="properties">
+									<div>
+										<?php if (!empty($theme['deprecated'])) { ?>
+											<span class="deprecated error"><?= _t('conf.display.theme.deprecated') ?>:</span>
+										<?php } ?>
+										<?= sprintf('%s — %s %s', $theme['name'], _t('gen.short.by_author'), $theme['author']) ?>
+									</div>
+									<div>
+										<?php if (!empty($theme['deprecated'])) { ?>
+											<span class="deprecated"><?= _t('conf.display.theme.deprecated.description') ?></span><br />
+										<?php } ?>
+										<?= $theme['description'] ?>
+									</div>
+									<?php if (!empty($theme['theme-color']['dark'])) { ?>
+										<div class="darkMode">✔ <?= _t('conf.display.darkMode') ?></div>
 									<?php } ?>
-									<?= $theme['description'] ?>
+
+								</div>
+								<div class="page-number">( <?= sprintf('%d/%d', $i, $slides) ?> )</div>
+							</li>
+							<?php $i++ ?>
+						<?php } ?>
+						<?php if (!$themeAvailable) {?>
+							<input type="radio" name="theme" checked="checked" value="Origine" />
+							<li class="preview-container">
+								<div class="preview">
+								</div>
+								<div class="nav">
+									<label for="img-<?= $i - 1 ?>" class="prev"><?= _i('prev') ?></label>
+								</div>
+								<div class="properties alert-error">
+									<div><?= _t('conf.display.theme_not_available', FreshRSS_Context::userConf()->theme)?></div>
 								</div>
-								<?php if (!empty($theme['theme-color']['dark'])) { ?>
-									<div class="darkMode">✔ <?= _t('conf.display.darkMode') ?></div>
-								<?php } ?>
-								<div class="page-number"><?= sprintf('%d/%d', $i, $slides) ?></div>
-							</div>
-						</li>
-						<?php $i++ ?>
-					<?php } ?>
-					<?php if (!$themeAvailable) {?>
-						<input type="radio" name="theme" checked="checked" value="Origine" />
-						<li class="preview-container">
-							<div class="preview">
-							</div>
-							<div class="nav">
-								<label for="img-<?= $i - 1 ?>" class="prev">‹</label>
-							</div>
-							<div class="properties alert-error">
-								<div><?= _t('conf.display.theme_not_available', FreshRSS_Context::userConf()->theme)?></div>
-							</div>
-						</li>
-					<?php }?>
-				</ul>
+							</li>
+						<?php }?>
+					</ul>
+				</div>
 			</div>
 		</div>
 

+ 4 - 0
p/themes/Dark-pink/pinkdark.css

@@ -160,3 +160,7 @@ input:focus {
 #btn-add > img {
 	filter: brightness(0.75);
 }
+
+.theme-preview-list .nav label.btn:hover {
+	background-color: var(--background-color-hover);
+}

+ 4 - 0
p/themes/Dark-pink/pinkdark.rtl.css

@@ -160,3 +160,7 @@ input:focus {
 #btn-add > img {
 	filter: brightness(0.75);
 }
+
+.theme-preview-list .nav label.btn:hover {
+	background-color: var(--background-color-hover);
+}

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

@@ -290,7 +290,9 @@ th {
 	text-decoration: none;
 }
 
-a:hover .icon {
+a:hover .icon,
+button:hover .icon,
+.btn:hover .icon {
 	filter: brightness(1.5);
 	transition: 0.1s linear;
 }

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

@@ -290,7 +290,9 @@ th {
 	text-decoration: none;
 }
 
-a:hover .icon {
+a:hover .icon,
+button:hover .icon,
+.btn:hover .icon {
 	filter: brightness(1.5);
 	transition: 0.1s linear;
 }

+ 20 - 31
p/themes/base-theme/frss.css

@@ -2093,6 +2093,7 @@ html.slider-active {
 /*=== SLIDESHOW Theme Preview */
 /*==============*/
 .theme-preview-list {
+	margin: 0.5rem 1rem 2rem 1rem;
 	padding: 0;
 	display: block;
 	max-width: 640px;
@@ -2100,7 +2101,6 @@ html.slider-active {
 	border: 1px solid var(--frss-border-color);
 	position: relative;
 	min-width: 260px;
-	margin-bottom: 30px;
 }
 
 .theme-preview-list input {
@@ -2118,8 +2118,6 @@ html.slider-active {
 	top: 0;
 	opacity: 0;
 	position: absolute;
-	transform: scale(0);
-	transition: all .7s ease-in-out;
 }
 
 .theme-preview-list .preview img {
@@ -2130,22 +2128,16 @@ html.slider-active {
 .theme-preview-list .nav label {
 	padding: 0;
 	display: none;
-	width: 65px;
-	height: 100%;
-	color: var(--frss-font-color-light);
-	font-family: "Varela Round", sans-serif;
-	font-size: 9rem;
+	min-width: 50px;
+	min-height: 5rem;
 	position: absolute;
-	opacity: 0;
+	top: 34%;
 	z-index: 9;
-	cursor: pointer;
-	transition: opacity .2s;
 	text-align: center;
-	line-height: 2;
-	background-color: var(--frss-background-color-transparent);
-	text-shadow: 0px 0px 15px #000;
+	line-height: 5;
 }
 
+
 .theme-preview-list .properties {
 	padding: 5px;
 	background-color: var(--frss-background-color-transparent);
@@ -2158,35 +2150,32 @@ html.slider-active {
 	backdrop-filter: blur(3px);
 }
 
-.theme-preview-list .properties .page-number {
-	right: 5px;
-	top: 0;
+.theme-preview-list .page-number {
+	bottom: -1.5rem;
 	position: absolute;
+	display: none;
+	left: 0;
+	right: 0;
+	text-align: center;
 }
 
-.theme-preview-list .preview + .nav label {
-	opacity: 0.8;
-}
-
-.theme-preview-list .nav label:hover {
-	opacity: 1;
+.theme-preview-list .nav label.prev {
+	left: -1rem;
 }
 
-.theme-preview-list .nav .next {
-	right: 0;
+.theme-preview-list .nav label.next {
+	right: -1rem;
 }
 
 .theme-preview-list input:checked + .preview-container .preview {
 	opacity: 1;
 	transform: scale(1);
-	transition: opacity 1s ease-in-out;
-}
-
-.theme-preview-list input:checked + .preview-container .nav label {
-	display: block;
+	transition: opacity .5s ease-in-out;
 }
 
-.theme-preview-list input:checked + .preview-container .properties {
+.theme-preview-list input:checked + .preview-container .nav label,
+.theme-preview-list input:checked + .preview-container .properties,
+.theme-preview-list input:checked + .preview-container .page-number {
 	display: block;
 }
 

+ 20 - 31
p/themes/base-theme/frss.rtl.css

@@ -2093,6 +2093,7 @@ html.slider-active {
 /*=== SLIDESHOW Theme Preview */
 /*==============*/
 .theme-preview-list {
+	margin: 0.5rem 1rem 2rem 1rem;
 	padding: 0;
 	display: block;
 	max-width: 640px;
@@ -2100,7 +2101,6 @@ html.slider-active {
 	border: 1px solid var(--frss-border-color);
 	position: relative;
 	min-width: 260px;
-	margin-bottom: 30px;
 }
 
 .theme-preview-list input {
@@ -2118,8 +2118,6 @@ html.slider-active {
 	top: 0;
 	opacity: 0;
 	position: absolute;
-	transform: scale(0);
-	transition: all .7s ease-in-out;
 }
 
 .theme-preview-list .preview img {
@@ -2130,22 +2128,16 @@ html.slider-active {
 .theme-preview-list .nav label {
 	padding: 0;
 	display: none;
-	width: 65px;
-	height: 100%;
-	color: var(--frss-font-color-light);
-	font-family: "Varela Round", sans-serif;
-	font-size: 9rem;
+	min-width: 50px;
+	min-height: 5rem;
 	position: absolute;
-	opacity: 0;
+	top: 34%;
 	z-index: 9;
-	cursor: pointer;
-	transition: opacity .2s;
 	text-align: center;
-	line-height: 2;
-	background-color: var(--frss-background-color-transparent);
-	text-shadow: 0px 0px 15px #000;
+	line-height: 5;
 }
 
+
 .theme-preview-list .properties {
 	padding: 5px;
 	background-color: var(--frss-background-color-transparent);
@@ -2158,35 +2150,32 @@ html.slider-active {
 	backdrop-filter: blur(3px);
 }
 
-.theme-preview-list .properties .page-number {
-	left: 5px;
-	top: 0;
+.theme-preview-list .page-number {
+	bottom: -1.5rem;
 	position: absolute;
+	display: none;
+	right: 0;
+	left: 0;
+	text-align: center;
 }
 
-.theme-preview-list .preview + .nav label {
-	opacity: 0.8;
-}
-
-.theme-preview-list .nav label:hover {
-	opacity: 1;
+.theme-preview-list .nav label.prev {
+	right: -1rem;
 }
 
-.theme-preview-list .nav .next {
-	left: 0;
+.theme-preview-list .nav label.next {
+	left: -1rem;
 }
 
 .theme-preview-list input:checked + .preview-container .preview {
 	opacity: 1;
 	transform: scale(1);
-	transition: opacity 1s ease-in-out;
-}
-
-.theme-preview-list input:checked + .preview-container .nav label {
-	display: block;
+	transition: opacity .5s ease-in-out;
 }
 
-.theme-preview-list input:checked + .preview-container .properties {
+.theme-preview-list input:checked + .preview-container .nav label,
+.theme-preview-list input:checked + .preview-container .properties,
+.theme-preview-list input:checked + .preview-container .page-number {
 	display: block;
 }