Files
FreshRSS/app/views/configure/display.phtml
rid3r45 3e4d5bb041 Add option to hide sidebar by default (#8515) (#8528)
* Add option to hide sidebar by default (#8515)

Closes https://github.com/FreshRSS/FreshRSS/issues/8515

Changes proposed in this pull request:

- Add `sidebar_hidden_by_default` user preference (default: `false`)
- Add a checkbox in the Display settings page to toggle this preference
- Hide the sidebar on page load in `normal` and `reader` views when the preference is enabled and no session state exists
- Add English translation key; mark all other languages as `TODO` for translators

How to test the feature manually:

1. Go to Settings → Display, tick "Hide sidebar by default", save
2. Go back to the main view (normal or reader): the sidebar should be hidden on load
3. Toggle the sidebar manually — it should open/stay open for the rest of the session
4. Open a new tab: the sidebar should be hidden again
5. Go to Settings → Display, untick the option, save: the sidebar should now be visible on load as usual
6. Check that the sidebar is always visible on Settings pages regardless of the preference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR comment

* Update app/i18n/pl/conf.php

* i18n: fr

* make fix-all

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Inverle <inverle@proton.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-02 13:32:10 +01:00

296 lines
13 KiB
PHTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
/** @var FreshRSS_View $this */
$this->partial('aside_configure');
?>
<main class="post">
<h1><?= _t('conf.display') ?></h1>
<form method="post" action="<?= _url('configure', 'display') ?>" data-auto-leave-validation="1">
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
<div class="form-group">
<label class="group-name" for="language"><?= _t('conf.display.language') ?></label>
<div class="group-controls">
<select name="language" id="language">
<?php $languages = Minz_Translate::availableLanguages(); ?>
<?php foreach ($languages as $lang) { ?>
<option value="<?= $lang ?>"<?= FreshRSS_Context::userConf()->language === $lang ? ' selected="selected"' : '' ?>><?= _t('gen.lang.' . $lang) ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label class="group-name" for="timezone"><?= _t('conf.display.timezone') ?></label>
<div class="group-controls">
<select name="timezone" id="timezone">
<?php
$timezones = array_merge([''], DateTimeZone::listIdentifiers());
if (!in_array(FreshRSS_Context::userConf()->timezone, $timezones, true)) {
FreshRSS_Context::userConf()->timezone = '';
}
?>
<?php foreach ($timezones as $timezone): ?>
<option value="<?= $timezone ?>"<?= FreshRSS_Context::userConf()->timezone === $timezone ? ' selected="selected"' : '' ?>>
<?= $timezone == '' ? _t('gen.short.by_default') . ' (' . FreshRSS_Context::defaultTimeZone() . ')' : $timezone ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-group">
<label class="group-name" for="theme"><?= _t('conf.display.theme') ?></label>
<div class="group-controls">
<select id="theme" name="theme">
<?php foreach ($this->themes as $theme): ?>
<option value="<?= $theme['id'] ?>"<?= FreshRSS_Context::userConf()->theme === $theme['id'] ? ' selected' : '' ?>><?= $theme['name'] ?></option>
<?php endforeach ?>
</select>
<ul class="theme-preview-list">
<?php $slides = count($this->themes); $i = 1; $themeAvailable = false; ?>
<?php
foreach ($this->themes as $theme) { ?>
<?php
$isCurrent = FreshRSS_Context::userConf()->theme === $theme['id'];
if ($isCurrent) {
$themeAvailable = true;
}
?>
<li class="preview-container<?= $isCurrent ? ' picked' : '' ?>" data-theme-preview="<?= $theme['id'] ?>">
<div class="preview">
<img src="<?= Minz_Url::display('/themes/' . $theme['id'] . '/thumbs/original.png') ?>" loading="lazy" />
</div>
<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 } ?>
</div>
</li>
<?php $i++ ?>
<?php } ?>
<?php if (!$themeAvailable) {?>
<li class="preview-container picked">
<div class="preview">
</div>
<div class="properties alert-error">
<div><?= _t('conf.display.theme_not_available', FreshRSS_Context::userConf()->theme)?></div>
</div>
</li>
<?php }?>
</ul>
</div>
</div>
<div class="form-group">
<label class="group-name" for="darkMode"><?= _t('conf.display.darkMode') ?></label>
<div class="group-controls">
<select name="darkMode" id="darkMode">
<option value="no"<?= FreshRSS_Context::userConf()->darkMode === 'no' ? ' selected' : '' ?>><?= _t('conf.display.darkMode.no') ?></option>
<option value="auto"<?= FreshRSS_Context::userConf()->darkMode === 'auto' ? ' selected' : '' ?>><?= _t('conf.display.darkMode.auto') ?></option>
</select>
<span class="help"><?= _i('help') ?> <?= _t('conf.display.darkMode.help') ?></span>
</div>
</div>
<?php $width = FreshRSS_Context::userConf()->content_width; ?>
<div class="form-group">
<label class="group-name" for="content_width"><?= _t('conf.display.width.content') ?></label>
<div class="group-controls">
<select name="content_width" id="content_width" required="">
<option value="thin" <?= $width === 'thin' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.width.thin') ?>
</option>
<option value="medium" <?= $width === 'medium' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.width.medium') ?>
</option>
<option value="large" <?= $width === 'large' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.width.large') ?>
</option>
<option value="no_limit" <?= $width === 'no_limit' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.width.no_limit') ?>
</option>
</select>
</div>
</div>
<?php $topline_website = FreshRSS_Context::userConf()->topline_website; ?>
<div class="form-group">
<label class="group-name" for="topline_website"><?= _t('conf.display.website.label') ?></label>
<div class="group-controls">
<select name="topline_website" id="topline_website" required="">
<option value="none" <?= $topline_website === 'none' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.website.none') ?>
</option>
<option value="icon" <?= $topline_website === 'icon' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.website.icon') ?>
</option>
<option value="name" <?= $topline_website === 'name' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.website.name') ?>
</option>
<option value="full" <?= $topline_website === 'full' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.website.full') ?>
</option>
</select>
</div>
</div>
<?php $topline_thumbnail = FreshRSS_Context::userConf()->topline_thumbnail; ?>
<div class="form-group">
<label class="group-name" for="topline_thumbnail"><?= _t('conf.display.thumbnail.label') ?></label>
<div class="group-controls">
<select name="topline_thumbnail" id="topline_thumbnail" required="">
<option value="none" <?= $topline_thumbnail === 'none' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.thumbnail.none') ?>
</option>
<option value="portrait" <?= $topline_thumbnail === 'portrait' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.thumbnail.portrait') ?>
</option>
<option value="square" <?= $topline_thumbnail === 'square' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.thumbnail.square') ?>
</option>
<option value="landscape" <?= $topline_thumbnail === 'landscape' ? 'selected="selected"' : '' ?>>
<?= _t('conf.display.thumbnail.landscape') ?>
</option>
</select>
</div>
</div>
<div class="form-group">
<label class="group-name"><?= _t('conf.display.icon.entry') ?></label>
<div class="group-controls">
<table class="config-articleicons">
<thead>
<tr>
<th> </th>
<th title="<?= _t('conf.shortcut.mark_read') ?>"><?= _i('read') ?></th>
<th title="<?= _t('conf.shortcut.mark_favorite') ?>"><?= _i('starred') ?></th>
<th title="<?= _t('index.menu.mylabels') ?>"><?= _i('label') ?></th>
<th title="<?= _t('conf.display.icon.related_tags') ?>"><?= _i('tag') ?></th>
<th title="<?= _t('conf.display.icon.sharing') ?>"><?= _i('share') ?></th>
<th><?= _t('conf.display.icon.summary') ?></th>
<th><?= _t('conf.display.icon.display_authors') ?></th>
<th><?= _t('conf.display.icon.publication_date') ?></th>
<th><?= _i('link') ?></th>
</tr>
</thead>
<tbody>
<tr>
<th><?= _t('conf.display.icon.top_line') ?></th>
<td><input type="checkbox" name="topline_read" value="1"<?=
FreshRSS_Context::userConf()->topline_read ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_favorite" value="1"<?=
FreshRSS_Context::userConf()->topline_favorite ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_myLabels" value="1"<?=
FreshRSS_Context::userConf()->topline_myLabels ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" disabled="disabled" /></td>
<td><input type="checkbox" name="topline_sharing" value="1"<?=
FreshRSS_Context::userConf()->topline_sharing ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_summary" value="1"<?=
FreshRSS_Context::userConf()->topline_summary ? 'checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_display_authors" value="1"<?=
FreshRSS_Context::userConf()->topline_display_authors ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_date" value="1"<?=
FreshRSS_Context::userConf()->topline_date ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="topline_link" value="1"<?= FreshRSS_Context::userConf()->topline_link ? ' checked="checked"' : '' ?> /></td>
</tr><tr>
<th><?= _t('conf.display.icon.bottom_line') ?></th>
<td><input type="checkbox" name="bottomline_read" value="1"<?=
FreshRSS_Context::userConf()->bottomline_read ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="bottomline_favorite" value="1"<?=
FreshRSS_Context::userConf()->bottomline_favorite ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="bottomline_myLabels" value="1"<?=
FreshRSS_Context::userConf()->bottomline_myLabels ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="bottomline_tags" value="1"<?=
FreshRSS_Context::userConf()->bottomline_tags ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="bottomline_sharing" value="1"<?=
FreshRSS_Context::userConf()->bottomline_sharing ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" disabled="disabled" /></td>
<td><input type="checkbox" disabled="disabled" /></td>
<td><input type="checkbox" name="bottomline_date" value="1"<?=
FreshRSS_Context::userConf()->bottomline_date ? ' checked="checked"' : '' ?> /></td>
<td><input type="checkbox" name="bottomline_link" value="1"<?=
FreshRSS_Context::userConf()->bottomline_link ? ' checked="checked"' : '' ?> /></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="html5_enable_notif">
<input type="checkbox" name="html5_enable_notif" id="html5_enable_notif" value="1"<?=
FreshRSS_Context::userConf()->html5_enable_notif ? ' checked="checked"' : '' ?> />
<?= _t('conf.notification.html5_enable_notif') ?>
</label>
</div>
</div>
<div class="form-group">
<label class="group-name" for="html5_notif_timeout"><?= _t('conf.display.notif_html5.timeout') ?></label>
<div class="group-controls">
<input type="number" min="0" max="60" id="html5_notif_timeout" name="html5_notif_timeout" value="<?=
FreshRSS_Context::userConf()->html5_notif_timeout ?>" /> <?= _t('conf.display.notif_html5.seconds') ?>
</div>
</div>
<div class="form-group">
<label class="group-name" for="good_notification_timeout"><?= _t('conf.notification_timeout.good.label') ?></label>
<div class="group-controls">
<input type="number" min="0" max="60" id="good_notification_timeout" name="good_notification_timeout" value="<?=
FreshRSS_Context::userConf()->good_notification_timeout ?>" /> <?= _t('conf.notification_timeout.good.seconds') ?>
</div>
</div>
<div class="form-group">
<label class="group-name" for="bad_notification_timeout"><?= _t('conf.notification_timeout.bad.label') ?></label>
<div class="group-controls">
<input type="number" min="1" max="60" id="bad_notification_timeout" name="bad_notification_timeout" value="<?=
FreshRSS_Context::userConf()->bad_notification_timeout ?>" /> <?= _t('conf.notification_timeout.bad.seconds') ?>
</div>
</div>
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="show_nav_buttons">
<input type="checkbox" name="show_nav_buttons" id="show_nav_buttons" value="1"<?=
FreshRSS_Context::userConf()->show_nav_buttons ? ' checked="checked"' : '' ?> />
<?= _t('conf.display.show_nav_buttons') ?>
</label>
</div>
</div>
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="sidebar_hidden_by_default">
<input type="checkbox" name="sidebar_hidden_by_default" id="sidebar_hidden_by_default" value="1"<?=
FreshRSS_Context::userConf()->sidebar_hidden_by_default ? ' checked="checked"' : '' ?> />
<?= _t('conf.display.sidebar_hidden_by_default') ?>
</label>
</div>
</div>
<div class="form-group form-actions">
<div class="group-controls">
<button type="submit" class="btn btn-important"><?= _t('gen.action.submit') ?></button>
<button type="reset" class="btn"><?= _t('gen.action.cancel') ?></button>
</div>
</div>
</form>
</main>