Search per tab, style, db update

This commit is contained in:
rogier committed 2025-10-06 21:56:58 +02:00
1 parent 80ddd17d45
commit 9b43c28ee3
10 files changed
+148 -58

No files matched your search

+5 -3
View File
@@ -19,8 +19,8 @@ try {
// Create a new tab
$data = json_decode(file_get_contents('php://input'), true);
if (isset($data['name'])) {
$stmt = $pdo->prepare("INSERT INTO tabs (name, user_id) VALUES (?, ?)");
$stmt->execute([$data['name'], $data['user_id'] ?? null]);
$stmt = $pdo->prepare("INSERT INTO tabs (name, user_id, show_search_bar) VALUES (?, ?, ?)");
$stmt->execute([$data['name'], $data['user_id'] ?? null, $data['show_search_bar'] ?? 1]);
$response = ['id' => $pdo->lastInsertId(), 'name' => $data['name']];
} else {
http_response_code(400); // Bad Request
@@ -42,6 +42,7 @@ try {
'theme' => $data['theme'] ?? null,
'theme_transparency' => $data['theme_transparency'] ?? null,
'column_count' => $data['column_count'] ?? 5,
'show_search_bar' => $data['show_search_bar'] ?? 1,
];
// Handle empty strings to set them to NULL for proper fallback
@@ -65,7 +66,8 @@ try {
background_saturation = :background_saturation,
theme = :theme,
theme_transparency = :theme_transparency,
column_count = :column_count
column_count = :column_count,
show_search_bar = :show_search_bar
WHERE id = :id
");
+13 -1
View File
@@ -23,7 +23,8 @@ try {
'background_saturation' => 'INTEGER DEFAULT 100',
'theme' => 'TEXT DEFAULT NULL',
'theme_transparency' => 'INTEGER DEFAULT NULL',
'login_token' => 'VARCHAR(255)'
'login_token' => 'VARCHAR(255)',
'show_search_bar' => 'INTEGER DEFAULT 1'
];
$columns_added = false;
@@ -77,6 +78,17 @@ try {
}
}
// --- Check settings table for show_search_bar setting ---
$settings_check = $pdo->prepare("SELECT value FROM settings WHERE key = 'show_search_bar'");
$settings_check->execute();
if (!$settings_check->fetch()) {
$pdo->prepare("INSERT INTO settings (key, value) VALUES (?, ?)")->execute(['show_search_bar', '1']);
$messages[] = "Added 'show_search_bar' setting to settings table.";
$columns_added = true;
} else {
$messages[] = "Setting 'show_search_bar' already exists in settings table.";
}
if ($columns_added) {
echo json_encode(['success' => true, 'message' => 'Database updated successfully!', 'details' => $messages]);
} else {
+49 -8
View File
@@ -192,9 +192,6 @@ body.dark-background-active .form-text,
}
/* Custom styles for transparent theme */
[data-bs-theme="transparent"] {
/* Transparent theme styles can be added here if needed */
}
/* New navbar layout */
.container-fluid {
@@ -232,20 +229,64 @@ body.user-settings-page .search-container-center {
position: absolute;
left: 50%;
transform: translateX(-50%);
max-width: 600px;
max-width: 500px;
width: 100%;
z-index: 10;
}
.search-container-center .input-group {
border-radius: 25px;
overflow: hidden;
background-color: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.search-container-center .form-control {
font-size: 1.1rem;
padding: 0.75rem 1rem;
font-size: 1rem;
padding: 0.6rem 1rem;
height: auto;
border: none;
background-color: transparent;
color: white;
box-shadow: none;
}
.search-container-center .form-control:focus {
border: none;
box-shadow: none;
background-color: transparent;
outline: none;
}
.search-container-center .form-control::placeholder {
color: rgba(255, 255, 255, 0.6);
}
.search-container-center .btn {
padding: 0.75rem 1rem;
font-size: 1.1rem;
padding: 0.6rem 0.8rem;
font-size: 1rem;
background-color: transparent;
border: none;
color: rgba(255, 255, 255, 0.7);
transition: all 0.2s ease;
}
.search-container-center .btn:hover {
background-color: rgba(255, 255, 255, 0.1);
color: white;
}
/* Reset button styling */
.search-container-center #searchResetButton {
background-color: transparent;
border: none;
color: rgba(255, 255, 255, 0.5);
}
.search-container-center #searchResetButton:hover {
background-color: rgba(255, 255, 255, 0.1);
color: white;
}
.search-results {
+20 -4
View File
@@ -115,18 +115,34 @@ if ($theme === 'dark' || in_array('dark-background-active', $body_classes)) {
</div>
<!-- Center: Search Bar -->
<?php
// Check if search bar should be shown
$show_search_bar = true;
// First check global setting
if (($settings['show_search_bar'] ?? '1') !== '1') {
$show_search_bar = false;
}
// Then check tab-specific setting if current tab data is available
if (isset($current_tab_data) && $current_tab_data && isset($current_tab_data['show_search_bar'])) {
$show_search_bar = ($current_tab_data['show_search_bar'] == 1);
}
if ($show_search_bar): ?>
<div class="search-container-center">
<div class="input-group search">
<input type="text" class="form-control" id="searchInput" placeholder="<?php echo translate('index_search_placeholder'); ?>" autocomplete="off">
<button class="btn btn-outline-secondary" type="button" id="searchButton">
<i class="bi bi-search"></i>
<button class="btn btn-outline-secondary" type="button" id="searchResetButton" style="display: none;">
<i class="bi bi-x"></i>
</button>
<button class="btn btn-outline-secondary" type="button" id="searchEngineButton" title="Zoek op internet">
<i class="bi bi-globe"></i>
<button class="btn btn-primary" type="button" id="searchButton">
<i class="bi bi-search"></i>
</button>
</div>
<div id="searchResults" class="search-results"></div>
</div>
<?php endif; ?>
<!-- Right side: Navigation -->
<div class="navbar-right">
+13
View File
@@ -53,6 +53,13 @@ if ($db_initialized) {
$pdo->exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user'");
$pdo->exec("UPDATE users SET role = 'admin' WHERE id = 1");
}
// Add show_search_bar setting if it doesn't exist
$stmt = $pdo->prepare("SELECT value FROM settings WHERE key = 'show_search_bar'");
$stmt->execute();
if (!$stmt->fetch()) {
$pdo->prepare("INSERT INTO settings (key, value) VALUES (?, ?)")->execute(['show_search_bar', '1']);
}
}
if (!$db_initialized) {
@@ -85,6 +92,7 @@ if (!$db_initialized) {
'language' => 'en',
'favicon_extractor_url' => 'https://favicon.hibbit.cloud',
'debug_mode' => '0',
'show_search_bar' => '1',
'theme' => 'transparent',
'background_image_url' => '',
'background_brightness' => '50',
@@ -174,6 +182,11 @@ if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'column_count')) {
$pdo->exec("ALTER TABLE tabs ADD COLUMN column_count INTEGER DEFAULT 5");
}
// Migration: Add show_search_bar to tabs table if it doesn't exist
if (tableExists($pdo, 'tabs') && !columnExists($pdo, 'tabs', 'show_search_bar')) {
$pdo->exec("ALTER TABLE tabs ADD COLUMN show_search_bar INTEGER DEFAULT 1");
}
// Check if tab_id column exists in bookmarks table
if (!columnExists($pdo, 'bookmarks', 'tab_id')) {
$pdo->exec("ALTER TABLE bookmarks ADD COLUMN tab_id INTEGER");
+17 -33
View File
@@ -394,9 +394,10 @@ function optimizeImage(path) {
function initSearch() {
const searchInput = document.getElementById('searchInput');
const searchButton = document.getElementById('searchButton');
const searchEngineButton = document.getElementById('searchEngineButton');
const searchResetButton = document.getElementById('searchResetButton');
const searchResults = document.getElementById('searchResults');
// Check if search bar is enabled and elements exist
if (!searchInput || !searchResults) return;
let searchTimeout;
@@ -410,6 +411,13 @@ function initSearch() {
clearTimeout(searchTimeout);
const query = this.value.trim();
// Show/hide reset button based on input content
if (query.length > 0) {
searchResetButton.style.display = 'block';
} else {
searchResetButton.style.display = 'none';
}
if (query.length < 2) {
hideSearchResults();
return;
@@ -430,16 +438,17 @@ function initSearch() {
});
}
// Search engine button click
if (searchEngineButton) {
searchEngineButton.addEventListener('click', function() {
const query = searchInput.value.trim();
if (query) {
searchOnWeb(query);
}
// Reset button click
if (searchResetButton) {
searchResetButton.addEventListener('click', function() {
searchInput.value = '';
searchResetButton.style.display = 'none';
hideSearchResults();
searchInput.focus();
});
}
// Hide search results when clicking outside
document.addEventListener('click', function(event) {
if (!searchInput.contains(event.target) && !searchResults.contains(event.target)) {
@@ -525,20 +534,6 @@ function initSearch() {
</div>
`;
} else {
// Add search engine options
searchResults.innerHTML = `
<div class="search-engine-results">
<div class="search-engine-item" onclick="searchOnWeb('${query}')">
<i class="bi bi-globe me-2"></i>
Zoek "${query}" op Google
</div>
<div class="search-engine-item" onclick="searchOnDuckDuckGo('${query}')">
<i class="bi bi-search me-2"></i>
Zoek "${query}" op DuckDuckGo
</div>
</div>
`;
// Add bookmark results
results.forEach(bookmark => {
const resultItem = document.createElement('div');
@@ -576,14 +571,3 @@ function initSearch() {
searchResults.classList.remove('show');
}
}
// Search engine functions
function searchOnWeb(query) {
const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
window.open(searchUrl, '_blank');
}
function searchOnDuckDuckGo(query) {
const searchUrl = `https://duckduckgo.com/?q=${encodeURIComponent(query)}`;
window.open(searchUrl, '_blank');
}
+3
View File
@@ -70,6 +70,7 @@ return [
'settings_favicon_extractor_url' => 'Favicon Extractor Base URL',
'settings_favicon_extractor_url_help' => 'Provide the service base URL (e.g., http://localhost:3000). The path /favicon/{URL}?larger=true will be appended automatically.',
'settings_debug_mode' => 'Enable Debug mode',
'settings_show_search_bar' => 'Show search bar',
'settings_save_settings_button' => 'Save Settings',
'settings_user_account_title' => 'User Account',
'settings_new_password' => 'New Password (leave blank to keep current)',
@@ -146,4 +147,6 @@ return [
'tab_clear_token_confirm' => 'Are you sure you want to clear the login token? The unique URL will no longer work.',
'tooltip_copy_to_clipboard' => 'Copy to clipboard',
'tooltip_copied' => 'Copied!',
'tab_show_search_bar' => 'Show search bar',
'tab_show_search_bar_help' => 'Enable or disable the search bar for this specific tab. This overrides the global search bar setting.',
];
+3
View File
@@ -70,6 +70,7 @@ return [
'settings_favicon_extractor_url' => 'Favicon Extractor Basis URL',
'settings_favicon_extractor_url_help' => 'Geef de basis-URL van de service op (bijv. http://localhost:3000). Het pad /favicon/{URL}?larger=true wordt automatisch toegevoegd.',
'settings_debug_mode' => 'Foutopsporingsmodus inschakelen',
'settings_show_search_bar' => 'Zoekbalk weergeven',
'settings_save_settings_button' => 'Instellingen Opslaan',
'settings_user_account_title' => 'Gebruikersaccount',
'settings_new_password' => 'Nieuw Wachtwoord (laat leeg om huidige te behouden)',
@@ -147,6 +148,8 @@ return [
'tab_clear_token_confirm' => 'Weet je zeker dat je de inlog-token wilt wissen? De unieke URL werkt dan niet meer.',
'tooltip_copy_to_clipboard' => 'Kopieer naar klembord',
'tooltip_copied' => 'Gekopieerd!',
'tab_show_search_bar' => 'Zoekbalk weergeven',
'tab_show_search_bar_help' => 'Schakel de zoekbalk in of uit voor dit specifieke tabblad. Dit overschrijft de globale zoekbalk instelling.',
// Search functionality
'search_placeholder' => 'Zoeken (Ctrl+K)',
+5 -1
View File
@@ -31,7 +31,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
// Handle checkboxes separately, as they are not sent when unchecked
$checkboxes = ['display_site_title', 'open_new_tab', 'dashboard_protected'];
$checkboxes = ['display_site_title', 'open_new_tab', 'dashboard_protected', 'show_search_bar'];
foreach ($checkboxes as $key) {
$upsert_stmt->execute([$key, isset($_POST[$key]) ? '1' : '0']);
}
@@ -292,6 +292,10 @@ require_once 'include/header.php';
<input class="form-check-input" type="checkbox" role="switch" id="dashboard_protected" name="dashboard_protected" value="1" <?php echo ($settings['dashboard_protected'] ?? '0') === '1' ? 'checked' : ''; ?>>
<label class="form-check-label" for="dashboard_protected"><?php echo translate('settings_dashboard_protection'); ?></label>
</div>
<div class="mb-3 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="show_search_bar" name="show_search_bar" value="1" <?php echo ($settings['show_search_bar'] ?? '1') === '1' ? 'checked' : ''; ?>>
<label class="form-check-label" for="show_search_bar"><?php echo translate('settings_show_search_bar'); ?></label>
</div>
<div class="mb-3">
<label for="remember_me_duration" class="form-label"><?php echo translate('settings_stay_logged_in'); ?></label>
<select class="form-select" id="remember_me_duration" name="remember_me_duration">
+20 -8
View File
@@ -87,13 +87,22 @@ require_once 'include/header.php';
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="edit-tab-column-count" class="form-label">Column Count (Tablet/Desktop)</label>
<select id="edit-tab-column-count" class="form-select">
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
<div class="row">
<div class="col-md-6 mb-3">
<label for="edit-tab-column-count" class="form-label">Column Count (Tablet/Desktop)</label>
<select id="edit-tab-column-count" class="form-select">
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<div class="col-md-6 mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="edit-tab-show-search-bar" name="edit-tab-show-search-bar">
<label class="form-check-label" for="edit-tab-show-search-bar"><?php echo translate('tab_show_search_bar'); ?></label>
</div>
<div class="form-text"><?php echo translate('tab_show_search_bar_help'); ?></div>
</div>
</div>
<div class="mb-3">
<label for="edit-tab-login-url" class="form-label"><?php echo translate('tab_unique_url_label'); ?></label>
@@ -365,6 +374,7 @@ document.addEventListener('DOMContentLoaded', function() {
document.getElementById('edit-tab-name').value = tabData.name;
document.getElementById('edit-tab-owner').value = tabData.user_id || '';
document.getElementById('edit-tab-column-count').value = tabData.column_count || '5';
document.getElementById('edit-tab-show-search-bar').checked = (tabData.show_search_bar ?? 1) == 1;
// Populate login url
const loginUrlInput = document.getElementById('edit-tab-login-url');
@@ -510,6 +520,7 @@ document.addEventListener('DOMContentLoaded', function() {
const name = document.getElementById('edit-tab-name').value.trim();
const ownerId = document.getElementById('edit-tab-owner').value;
const columnCount = document.getElementById('edit-tab-column-count').value;
const showSearchBar = document.getElementById('edit-tab-show-search-bar').checked ? 1 : 0;
// Get theme and background values from the other modal's inputs
const theme = document.getElementById('edit-tab-theme').value;
@@ -529,6 +540,7 @@ document.addEventListener('DOMContentLoaded', function() {
name: name,
user_id: ownerId,
column_count: columnCount,
show_search_bar: showSearchBar,
theme: theme,
theme_transparency: transparency,
background_image_url: backgroundUrl,
@@ -555,7 +567,7 @@ document.addEventListener('DOMContentLoaded', function() {
await fetch('api/tabs.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: name, user_id: userId })
body: JSON.stringify({ name: name, user_id: userId, show_search_bar: 1 })
});
newTabNameInput.value = '';
newTabUserInput.value = '';