diff --git a/admin.php b/admin.php index a00d93ee5..365221948 100644 --- a/admin.php +++ b/admin.php @@ -236,6 +236,10 @@ class="one-third" value="" /> " />
+

+
+ +
+

.

+

+ : + + + + + + +

+

+ : + + + + + + +

+
+ + + +
+
+ onchange="toggleUpdateNotification()"/> + +

> /var/log/cron/sendnotifications.log 2>&1 */2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendverificationemails.php >> /var/log/cron/sendverificationemails.log 2>&1 */2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendresetpasswordemails.php >> /var/log/cron/sendresetpasswordemails.log 2>&1 +0 */6 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/checkforupdates.php >> /var/log/cron/checkforupdates.log 2>&1 diff --git a/endpoints/admin/updatenotification.php b/endpoints/admin/updatenotification.php new file mode 100644 index 000000000..dfa00c5d3 --- /dev/null +++ b/endpoints/admin/updatenotification.php @@ -0,0 +1,46 @@ + false, + "message" => translate('session_expired', $i18n) + ])); +} + +// Check that user is an admin +if ($userId !== 1) { + die(json_encode([ + "success" => false, + "message" => translate('error', $i18n) + ])); +} + +if ($_SERVER["REQUEST_METHOD"] === "POST") { + + $postData = file_get_contents("php://input"); + $data = json_decode($postData, true); + + $updateNotification = $data['notificationEnabled']; + + // Save settings + $stmt = $db->prepare('UPDATE admin SET update_notification = :update_notification'); + $stmt->bindValue(':update_notification', $updateNotification, SQLITE3_INTEGER); + $result = $stmt->execute(); + + if ($result) { + die(json_encode([ + "success" => true, + "message" => translate('success', $i18n) + ])); + } else { + die(json_encode([ + "success" => false, + "message" => translate('error', $i18n) + ])); + } + +} + +?> \ No newline at end of file diff --git a/endpoints/cronjobs/checkforupdates.php b/endpoints/cronjobs/checkforupdates.php new file mode 100644 index 000000000..32bcb64e7 --- /dev/null +++ b/endpoints/cronjobs/checkforupdates.php @@ -0,0 +1,30 @@ + [ + 'header' => "User-Agent: MyApp\r\n" + ] +]; + +$repository = 'ellite/Wallos'; // Change this to your repository if you fork Wallos +$url = "https://api.github.com/repos/$repository/releases/latest"; + +$context = stream_context_create($options); +$fetch = file_get_contents($url, false, $context); + +if ($fetch === false) { + die('Error fetching data from GitHub API'); +} + +$latestVersion = json_decode($fetch, true)['tag_name']; + +// Check that $latestVersion is a valid version number +if (!preg_match('/^v\d+\.\d+\.\d+$/', $latestVersion)) { + die('Error: Invalid version number from GitHub API'); +} + +$db->exec("UPDATE admin SET latest_version = '$latestVersion'"); + +?> \ No newline at end of file diff --git a/endpoints/settings/disabled_to_bottom.php b/endpoints/settings/disabled_to_bottom.php new file mode 100644 index 000000000..722a7eb52 --- /dev/null +++ b/endpoints/settings/disabled_to_bottom.php @@ -0,0 +1,34 @@ + false, + "message" => translate('session_expired', $i18n) + ])); +} + +if ($_SERVER["REQUEST_METHOD"] === "POST") { + $postData = file_get_contents("php://input"); + $data = json_decode($postData, true); + + $disabled_to_bottom = $data['value']; + + $stmt = $db->prepare('UPDATE settings SET disabled_to_bottom = :disabled_to_bottom WHERE user_id = :userId'); + $stmt->bindParam(':disabled_to_bottom', $disabled_to_bottom, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + + if ($stmt->execute()) { + die(json_encode([ + "success" => true, + "message" => translate("success", $i18n) + ])); + } else { + die(json_encode([ + "success" => false, + "message" => translate("error", $i18n) + ])); + } +} + +?> \ No newline at end of file diff --git a/endpoints/subscriptions/get.php b/endpoints/subscriptions/get.php index 98fd9a28f..0eacce5fd 100644 --- a/endpoints/subscriptions/get.php +++ b/endpoints/subscriptions/get.php @@ -19,24 +19,11 @@ } if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { + + $sort = "next_payment"; $sortOrder = $sort; $order = "ASC"; - $sql = "SELECT * FROM subscriptions ORDER BY next_payment ASC, inactive ASC"; - if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") { - $sort = $_COOKIE['sortOrder']; - $sortOrder = $sort; - $allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id', 'inactive', 'alphanumeric']; - if ($sort == "price" || $sort == "id") { - $order = "DESC"; - } - if ($sort == "alphanumeric") { - $sort = "name"; - } - if (!in_array($sort, $allowedSortCriteria)) { - $sort = "next_payment"; - } - } $params = array(); $sql = "SELECT * FROM subscriptions WHERE user_id = :userId"; @@ -61,12 +48,41 @@ $params[':inactive'] = $_GET['state']; } - $sql .= " ORDER BY LOWER($sort) $order"; - if ($sort != "next_payment") { - $sql .= ", next_payment ASC"; - } - if ($sort != "state") { - $sql .= ", inactive ASC"; + if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") { + $sort = $_COOKIE['sortOrder']; + $allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id', 'inactive', 'alphanumeric']; + $order = ($sort == "price" || $sort == "id") ? "DESC" : "ASC"; + + if ($sort == "alphanumeric") { + $sort = "name"; + } + + if (!in_array($sort, $allowedSortCriteria)) { + $sort = "next_payment"; + } + + $orderByClauses = []; + + if ($settings['disabledToBottom'] === 'true') { + if (in_array($sort, ["payer_user_id", "category_id", "payment_method_id"])) { + $orderByClauses[] = "$sort $order"; + $orderByClauses[] = "inactive ASC"; + } else { + $orderByClauses[] = "inactive ASC"; + $orderByClauses[] = "$sort $order"; + } + } else { + $orderByClauses[] = "$sort $order"; + if ($sort != "inactive") { + $orderByClauses[] = "inactive ASC"; + } + } + + if ($sort != "next_payment") { + $orderByClauses[] = "next_payment ASC"; + } + + $sql .= " ORDER BY " . implode(", ", $orderByClauses); } $stmt = $db->prepare($sql); @@ -123,6 +139,22 @@ usort($print, function ($a, $b) { return strnatcmp(strtolower($a['name']), strtolower($b['name'])); }); + if ($settings['disabledToBottom'] === 'true') { + usort($print, function ($a, $b) { + return $a['inactive'] - $b['inactive']; + }); + } + } + + if ($sort === "price") { + usort($subscriptions, function ($a, $b) { + return $a['price'] < $b['price'] ? 1 : -1; + }); + if ($settings['disabledToBottom'] === 'true') { + usort($print, function ($a, $b) { + return $a['inactive'] - $b['inactive']; + }); + } } if (isset($print)) { diff --git a/includes/getsettings.php b/includes/getsettings.php index 7b35a0873..7def7ee62 100644 --- a/includes/getsettings.php +++ b/includes/getsettings.php @@ -27,6 +27,7 @@ $settings['convertCurrency'] = $settings['convert_currency'] ? 'true': 'false'; $settings['removeBackground'] = $settings['remove_background'] ? 'true': 'false'; $settings['hideDisabledSubscriptions'] = $settings['hide_disabled'] ? 'true': 'false'; + $settings['disabledToBottom'] = $settings['disabled_to_bottom'] ? 'true': 'false'; } $query = "SELECT * FROM custom_colors WHERE user_id = :userId"; @@ -54,6 +55,8 @@ if ($adminSettings) { $settings['disableLogin'] = $adminSettings['login_disabled']; + $settings['update_notification'] = $adminSettings['update_notification']; + $settings['latest_version'] = $adminSettings['latest_version']; } ?> \ No newline at end of file diff --git a/includes/i18n/de.php b/includes/i18n/de.php index 371cd32d5..398aa08b7 100644 --- a/includes/i18n/de.php +++ b/includes/i18n/de.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Berechne und zeige monatlichen Preis für alle Abonnements an", "convert_prices" => "Preise immer in meine Hauptwährung umrechnen und darin anzeigen (langsamer)", "hide_disabled_subscriptions" => "Deaktivierte Abonnements verstecken", + "show_disabled_subscriptions_at_the_bottom" => "Deaktivierte Abonnements am Ende anzeigen", "experimental_settings" => "Experimentelle Einstellungen", "remove_background" => "Versuchen den Hintergrund von Logos aus der Bildersuche zu entfernen (experimentell)", "experimental_info" => "Experimentelle Einstellungen funktionieren möglicherweise nicht perfekt.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Wird für die Passwortwiederherstellung und andere System-E-Mails verwendet", "maintenance_tasks" => "Wartungsaufgaben", "orphaned_logos" => "Verwaiste Logos", + "update" => "Update", + "new_version_available" => "Eine neue Version von Wallos ist verfügbar", + "current_version" => "Aktuelle Version", + "latest_version" => "Neueste Version", + "on_current_version" => "Sie verwenden die neueste Version von Wallos.", + "show_update_notification" => "Benachrichtigung über Updates auf dem Dashboard anzeigen", // Email Verification "email_verified" => "E-Mail verifiziert", "email_verification_failed" => "E-Mail konnte nicht verifiziert werden", diff --git a/includes/i18n/el.php b/includes/i18n/el.php index c3a1b8a70..b0c3bf44f 100644 --- a/includes/i18n/el.php +++ b/includes/i18n/el.php @@ -186,7 +186,7 @@ "theme" => "Θέμα", "dark_theme" => "Dark Theme", "light_theme" => "Light Theme", - "automatic"=> "Αυτόματο", + "automatic" => "Αυτόματο", "main_color" => "Κύριο χρώμα", "accent_color" => "Χρώμα επισήμανσης", "hover_color" => "Χρώμα πάνω από", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Υπολογισμός και εμφάνιση της μηνιαίας τιμής για όλες τις συνδρομές", "convert_prices" => "Πάντα να μετατρέπει και να εμφανίζει τις τιμές στο κύριο νόμισμά μου (πιο αργό)", "hide_disabled_subscriptions" => "Απόκρυψη απενεργοποιημένων συνδρομών", + "show_disabled_subscriptions_at_the_bottom" => "Εμφάνιση απενεργοποιημένων συνδρομών στο τέλος", "experimental_settings" => "Πειραματικές ρυθμίσεις", "remove_background" => "Προσπάθεια αφαίρεσης του φόντου των λογότυπων από την αναζήτηση εικόνας (πειραματικά)", "experimental_info" => "Οι πειραματικές ρυθμίσεις πιθανότατα δεν θα λειτουργούν τέλεια.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Θα χρησιμοποιηθεί για ανάκτηση κωδικού πρόσβασης και άλλα μηνύματα ηλεκτρονικού ταχυδρομείου συστήματος.", "maintenance_tasks" => "Εργασίες συντήρησης", "orphaned_logos" => "Ορφανά λογότυπα", + "update" => "Ενημέρωση", + "new_version_available" => "Μια νέα έκδοση του Wallos είναι διαθέσιμη", + "current_version" => "Τρέχουσα Έκδοση", + "latest_version" => "Τελευταία Έκδοση", + "on_current_version" => "Χρησιμοποιείτε την τελευταία έκδοση του Wallos.", + "show_update_notification" => "Εμφάνιση ειδοποίησης για ενημερώσεις στο dashboard", // Email Verification "email_verified" => "Το email επιβεβαιώθηκε", "email_verification_failed" => "Η επαλήθευση email απέτυχε", diff --git a/includes/i18n/en.php b/includes/i18n/en.php index 31176a8b7..6e84637ea 100644 --- a/includes/i18n/en.php +++ b/includes/i18n/en.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Calculate and show monthly price for all subscriptions", "convert_prices" => "Always convert and show prices on my main currency (slower)", "hide_disabled_subscriptions" => "Hide disabled subscriptions", + "show_disabled_subscriptions_at_the_bottom" => "Show disabled subscriptions at the bottom", "experimental_settings" => "Experimental Settings", "remove_background" => "Attempt to remove background of logos from image search (experimental)", "experimental_info" => "Experimental settings will probably not work perfectly.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Will be used for password recovery and other system emails.", "maintenance_tasks" => "Maintenance Tasks", "orphaned_logos" => "Orphaned Logos", + "update" => "Update", + "new_version_available" => "A new version of Wallos is available", + "current_version" => "Current Version", + "latest_version" => "Latest Version", + "on_current_version" => "You're running the latest version of Wallos.", + "show_update_notification" => "Show notification for updates on the dashboard", // Email Verification "email_verified" => "Email verified successfully", "email_verification_failed" => "Email verification failed", diff --git a/includes/i18n/es.php b/includes/i18n/es.php index 199efac5a..2ce4ef698 100644 --- a/includes/i18n/es.php +++ b/includes/i18n/es.php @@ -186,7 +186,7 @@ "theme" => "Tema", "dark_theme" => "Tema Oscuro", "light_theme" => "Tema Claro", - "automatic"=> "Automático", + "automatic" => "Automático", "main_color" => "Color Principal", "accent_color" => "Color de Acento", "hover_color" => "Color de Hover", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Calcular y mostrar el precio mensual de todas las suscripciones", "convert_prices" => "Convertir y mostrar siempre los precios en mi moneda principal (más lento)", "hide_disabled_subscriptions" => "Ocultar suscripciones desactivadas", + "show_disabled_subscriptions_at_the_bottom" => "Mostrar suscripciones desactivadas al final", "experimental_settings" => "Configuraciones Experimentales", "remove_background" => "Intentar quitar el fondo de los logotipos de la búsqueda de imágenes (experimental)", "experimental_info" => "Las configuraciones experimentales probablemente no funcionarán perfectamente.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Se utilizará para recuperar contraseñas y otros correos electrónicos del sistema.", "maintenance_tasks" => "Tareas de Mantenimiento", "orphaned_logos" => "Logotipos huérfanos", + "update" => "Actualizar", + "new_version_available" => "Una nueva versión de Wallos está disponible", + "current_version" => "Versión Actual", + "latest_version" => "Última Versión", + "on_current_version" => "Está utilizando la última versión de Wallos.", + "show_update_notification" => "Mostrar notificación de actualizaciones en el dashboard", // Email Verification "email_verified" => "Correo electrónico verificado", "email_verification_failed" => "Error al verificar el correo electrónico", diff --git a/includes/i18n/fr.php b/includes/i18n/fr.php index cbe6ac53d..cba8f0704 100644 --- a/includes/i18n/fr.php +++ b/includes/i18n/fr.php @@ -186,7 +186,7 @@ "theme" => "Thème", "dark_theme" => "Thème sombre", "light_theme" => "Thème clair", - "automatic"=> "Automatique", + "automatic" => "Automatique", "main_color" => "Couleur principale", "accent_color" => "Couleur d'accent", "hover_color" => "Couleur de survol", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Calculer et afficher le prix mensuel pour tous les abonnements", "convert_prices" => "Convertir toujours et afficher les prix dans ma devise principale (plus lent)", "hide_disabled_subscriptions" => "Masquer les abonnements désactivés", + "show_disabled_subscriptions_at_the_bottom" => "Afficher les abonnements désactivés en bas", "experimental_settings" => "Paramètres expérimentaux", "remove_background" => "Tenter de supprimer l'arrière-plan des logos de la recherche d'images (expérimental)", "experimental_info" => "Les paramètres expérimentaux ne fonctionneront probablement pas parfaitement.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Sera utilisé pour la récupération du mot de passe et d'autres e-mails système.", "maintenance_tasks" => "Tâches de maintenance", "orphaned_logos" => "Logos orphelins", + "update" => "Mise à jour", + "new_version_available" => "Une nouvelle version de Wallos est disponible", + "current_version" => "Version actuelle", + "latest_version" => "Dernière version", + "on_current_version" => "Vous utilisez la dernière version de Wallos.", + "show_update_notification" => "Afficher la notification de mise à jour sur le tableau de bord", // Email Verification "email_verified" => "Votre adresse courriel a été vérifiée avec succès", "email_verification_failed" => "La vérification de l'adresse courriel a échoué", diff --git a/includes/i18n/it.php b/includes/i18n/it.php index cc6c47ce1..ff441ef26 100644 --- a/includes/i18n/it.php +++ b/includes/i18n/it.php @@ -205,6 +205,7 @@ 'calculate_monthly_price' => 'Calcola e mostra il prezzo mensile per tutti gli abbonamenti', 'convert_prices' => 'Converti sempre e mostra i prezzi nella mia valuta principale (più lento)', "hide_disabled_subscriptions" => 'Nascondi gli abbonamenti disattivati', + "show_disabled_subscriptions_at_the_bottom" => 'Mostra gli abbonamenti disattivati in fondo', 'experimental_settings' => 'Impostazioni sperimentali', 'remove_background' => 'Prova a rimuovere lo sfondo dei loghi dalla ricerca delle immagini (sperimentale)', 'experimental_info' => 'Le impostazioni sperimentali potrebbero non funzioneranno perfettamente.', @@ -328,6 +329,12 @@ "smtp_usage_info" => "Verrà utilizzato per il recupero della password e altre e-mail di sistema.", "maintenance_tasks" => "Compiti di manutenzione", "orphaned_logos" => "Loghi orfani", + "update" => "Aggiorna", + "new_version_available" => "È disponibile una nuova versione di Wallos", + "current_version" => "Versione attuale", + "latest_version" => "Ultima versione", + "on_current_version" => "Stai utilizzando l'ultima versione di Wallos.", + "show_update_notification" => "Mostra notifica di aggiornamento sulla dashboard", // Email Verification "email_verified" => "L'indirizzo email è stato verificato con successo", diff --git a/includes/i18n/jp.php b/includes/i18n/jp.php index b55c9dfe1..5c9be3c2e 100644 --- a/includes/i18n/jp.php +++ b/includes/i18n/jp.php @@ -186,7 +186,7 @@ "theme" => "テーマ", "dark_theme" => "ダークテーマ", "light_theme" => "ライトテーマ", - "automatic"=> "自動", + "automatic" => "自動", "main_color" => "メインカラー", "accent_color" => "アクセントカラー", "hover_color" => "ホバーカラー", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "すべての定期購入の月額料金を計算して表示する", "convert_prices" => "常にメイン通貨で価格を換算して表示する (遅い)", "hide_disabled_subscriptions" => "無効な定期購入を非表示にする", + "show_disabled_subscriptions_at_the_bottom" => "無効な定期購入を一番下に表示する", "experimental_settings" => "実験的な設定", "remove_background" => "画像検索からロゴの背景を削除する (実験)", "experimental_info" => "実験的な設定は、おそらく完全には機能しません。", @@ -302,6 +303,12 @@ "smtp_usage_info" => "パスワードの回復やその他のシステム電子メールに使用されます。", "maintenance_tasks" => "メンテナンスタスク", "orphaned_logos" => "孤立したロゴ", + "update" => "更新", + "new_version_available" => "新しいバージョンのWallosが利用可能です", + "current_version" => "現在のバージョン", + "latest_version" => "最新バージョン", + "on_current_version" => "最新バージョンのWallosを使用しています。", + "show_update_notification" => "ダッシュボードに更新通知を表示する", // Email Verification "email_verified" => "メールアドレスが確認されました", "email_verification_failed" => "メールアドレスの確認に失敗しました", diff --git a/includes/i18n/ko.php b/includes/i18n/ko.php index 98aadce5e..d1eff9fb4 100644 --- a/includes/i18n/ko.php +++ b/includes/i18n/ko.php @@ -187,7 +187,7 @@ "theme" => "테마", "dark_theme" => "다크 테마", "light_theme" => "라이트 테마", - "automatic"=> "자동", + "automatic" => "자동", "main_color" => "메인 색상", "accent_color" => "강조 색상", "hover_color" => "마우스 호버 색상", @@ -198,6 +198,7 @@ "calculate_monthly_price" => "모든 구독에 대한 월별 요금을 계산하고 표시", "convert_prices" => "항상 기본 통화로 가격을 환산하고 표시 (느림)", "hide_disabled_subscriptions" => "비활성화된 구독 숨기기", + "show_disabled_subscriptions_at_the_bottom" => "비활성화된 구독을 하단에 표시", "experimental_settings" => "실험적 설정", "remove_background" => "로고 이미지 검색에서 배경 삭제 (실험적)", "experimental_info" => "실험적 설정은 제대로 작동하지 않을 수 있습니다.", @@ -310,6 +311,12 @@ "smtp_usage_info" => "비밀번호 복구 및 기타 시스템 이메일에 사용됩니다.", "maintenance_tasks" => "유지보수 작업", "orphaned_logos" => "고아 로고", + "update" => "업데이트", + "new_version_available" => "새로운 버전의 Wallos가 이용 가능합니다", + "current_version" => "현재 버전", + "latest_version" => "최신 버전", + "on_current_version" => "최신 버전의 Wallos를 사용 중입니다.", + "show_update_notification" => "대시보드에 업데이트 알림 표시", // Email Verification "email_verified" => "이메일 인증 완료", "email_verification_failed" => "이메일 인증 실패", diff --git a/includes/i18n/pl.php b/includes/i18n/pl.php index 233c82442..fa402cbe7 100644 --- a/includes/i18n/pl.php +++ b/includes/i18n/pl.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Oblicz i pokaż miesięczną cenę wszystkich subskrypcji", "convert_prices" => "Zawsze przeliczaj i pokazuj ceny w mojej głównej walucie (wolniej)", "hide_disabled_subscriptions" => "Ukryj wyłączone subskrypcje", + "show_disabled_subscriptions_at_the_bottom" => "Pokaż wyłączone subskrypcje na dole", "experimental_settings" => "Ustawienia eksperymentalne", "remove_background" => "Próba usunięcia tła logo z wyszukiwania obrazów (eksperymentalnie)", "experimental_info" => "Ustawienia eksperymentalne prawdopodobnie nie będą działać idealnie.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Będzie używany do odzyskiwania hasła i innych e-maili systemowych.", "maintenance_tasks" => "Zadania konserwacyjne", "orphaned_logos" => "Osierocone logo", + "update" => "Aktualizacja", + "new_version_available" => "Dostępna jest nowa wersja Wallos", + "current_version" => "Aktualna wersja", + "latest_version" => "Najnowsza wersja", + "on_current_version" => "Używasz najnowszej wersji Wallos.", + "show_update_notification" => "Pokaż powiadomienie o aktualizacjach na dashboardzie", // Email Verification "email_verified" => "E-mail został zweryfikowany", "email_verification_failed" => "Weryfikacja e-maila nie powiodła się", diff --git a/includes/i18n/pt.php b/includes/i18n/pt.php index 78717494e..ad2895c0e 100644 --- a/includes/i18n/pt.php +++ b/includes/i18n/pt.php @@ -186,7 +186,7 @@ "theme" => "Tema", "dark_theme" => "Tema Escuro", "light_theme" => "Tema Claro", - "automatic"=> "Automático", + "automatic" => "Automático", "main_color" => "Cor Principal", "accent_color" => "Cor de Destaque", "hover_color" => "Cor de Hover", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Calcular e mostrar preço mensal para todas as subscrições", "convert_prices" => "Converter e mostrar todas as subscrições na moeda principal (mais lento)", "hide_disabled_subscriptions" => "Esconder subscrições desactivadas", + "show_disabled_subscriptions_at_the_bottom" => "Mostrar subscrições desactivadas no fundo da lista", "experimental_settings" => "Definições Experimentais", "remove_background" => "Tentar remover o fundo dos logos na pesquisa de imagem (experimental)", "experimental_info" => "Definições experimentais provavelmente não funcionarão correctamente.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Será usado para recuperações de password e outros emails do sistema.", "maintenance_tasks" => "Tarefas de Manutenção", "orphaned_logos" => "Logos Órfãos", + "update" => "Actualizar", + "new_version_available" => "Uma nova versão do Wallos está disponível", + "current_version" => "Versão Atual", + "latest_version" => "Última Versão", + "on_current_version" => "Está a usar a versão mais recente do Wallos.", + "show_update_notification" => "Mostrar notificação de atualizações no dashboard", // Email Verification "email_verified" => "Email verificado", "email_verification_failed" => "Verificação de email falhou", @@ -336,4 +343,4 @@ ]; -?> +?> \ No newline at end of file diff --git a/includes/i18n/pt_br.php b/includes/i18n/pt_br.php index f8835d530..aa054e17c 100644 --- a/includes/i18n/pt_br.php +++ b/includes/i18n/pt_br.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Calcular e exibir o custo mensal para todas as assinaturas", "convert_prices" => "Sempre converter e exibir preços na moeda principal (mais lento)", "hide_disabled_subscriptions" => "Ocultar assinaturas desativadas", + "show_disabled_subscriptions_at_the_bottom" => "Mostre as assinaturas desativadas no final da lista", "experimental_settings" => "Configurações experimentais", "remove_background" => "Tentar remover o fundo de logos na pesquisa de imagem", "experimental_info" => "As configurações experimentais provavelmente não funcionarão corretamente", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Será usado para recuperação de senha e outros e-mails do sistema.", "maintenance_tasks" => "Tarefas de manutenção", "orphaned_logos" => "Logos órfãos", + "update" => "Atualizar", + "new_version_available" => "Nova versão do Wallos disponível", + "current_version" => "Versão atual", + "latest_version" =>"Última versão", + "on_current_version" => "Você está na última versão do Wallos.", + "show_update_notification" => "Mostrar notificação de atualização no dashboard", // Email Verification "email_verified" => "Email verificado", "email_verification_failed" => "Falha na verificação do email", diff --git a/includes/i18n/ru.php b/includes/i18n/ru.php index 2f784702a..fb78e8771 100644 --- a/includes/i18n/ru.php +++ b/includes/i18n/ru.php @@ -186,7 +186,7 @@ "theme" => "Тема", "dark_theme" => "Темная тема", "light_theme" => "Светлая тема", - "automatic"=> "Автоматически", + "automatic" => "Автоматически", "main_color" => "Основной цвет", "accent_color" => "Акцентный цвет", "hover_color" => "Цвет при наведении", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Рассчитать и показать ежемесячную цену для всех подписок", "convert_prices" => "Всегда конвертировать и показывать цены в моей основной валюте (медленнее)", "hide_disabled_subscriptions" => "Скрыть отключенные подписки", + "show_disabled_subscriptions_at_the_bottom" => "Показать отключенные подписки внизу списка", "experimental_settings" => "Экспериментальные настройки", "remove_background" => "Попытка удалить фон логотипов из поиска изображений (экспериментально).", "experimental_info" => "Экспериментальные настройки, вероятно, не будут работать идеально.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Будет использоваться для восстановления пароля и других системных писем.", "maintenance_tasks" => "Задачи обслуживания", "orphaned_logos" => "Одинокие логотипы", + "update" => "Обновить", + "new_version_available" => "Доступна новая версия Wallos", + "current_version" => "Текущая версия", + "latest_version" => "Последняя версия", + "on_current_version" => "Вы используете последнюю версию Wallos.", + "show_update_notification" => "Показывать уведомление об обновлениях на дашборде", // Email Verification "email_verified" => "Ваш адрес электронной почты подтвержден. Теперь вы можете войти.", "email_verification_failed" => "Не удалось подтвердить ваш адрес электронной почты.", diff --git a/includes/i18n/sl.php b/includes/i18n/sl.php index e14a0a703..c1960c790 100644 --- a/includes/i18n/sl.php +++ b/includes/i18n/sl.php @@ -186,7 +186,7 @@ "theme" => "Tema", "dark_theme" => "Temna tema", "light_theme" => "Svetla tema", - "automatic"=> "Samodejno", + "automatic" => "Samodejno", "main_color" => "Glavna barva", "accent_color" => "Poudarna barva", "hover_color" => "Barva ob hoverju", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Izračunaj in prikaži mesečno ceno za vse naročnine", "convert_prices" => "Vedno pretvori in prikaži cene v moji glavni valuti (počasneje)", "hide_disabled_subscriptions" => "Skrij onemogočene naročnine", + "show_disabled_subscriptions_at_the_bottom" => "Prikaži onemogočene naročnine na dnu seznama", "experimental_settings" => "Eksperimentalne nastavitve", "remove_background" => "Poskusi odstraniti ozadje logotipov iz iskanja slik (eksperimentalno)", "experimental_info" => "Poskusne nastavitve verjetno ne bodo popolnoma delovale.", @@ -302,6 +303,12 @@ "smtp_usage_info" => "Uporabljeno bo za obnovitev gesla in druge sistemske e-pošte.", "maintenance_tasks" => "Vzdrževalne naloge", "orphaned_logos" => "Osamljeni logotipi", + "update" => "Posodobi", + "new_version_available" => "Na voljo je nova različica Wallos", + "current_version" => "Trenutna različica", + "latest_version" => "Najnovejša različica", + "on_current_version" => "Uporabljate najnovejšo različico Wallos.", + "show_update_notification" => "Prikaži obvestilo o posodobitvah na dashboardu", // Email Verification "email_verified" => "E-pošta je bila uspešno preverjena", "email_verification_failed" => "Preverjanje e-pošte ni uspelo", diff --git a/includes/i18n/sr.php b/includes/i18n/sr.php index a8c008f5e..3f17d6278 100644 --- a/includes/i18n/sr.php +++ b/includes/i18n/sr.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Израчунајте и прикажите месечну цену за све претплате", "convert_prices" => "Увек конвертујте и прикажите цене на мојој главној валути (спорије)", "hide_disabled_subscriptions" => "Сакриј онемогућене претплате", + "show_disabled_subscriptions_at_the_bottom" => "Прикажи онемогућене претплате на дну", "experimental_settings" => "Експериментална подешавања", "remove_background" => "Покушајте уклонити позадину логотипа са слика претраге (експериментално)", "experimental_info" => "Експериментална подешавања вероватно неће радити савршено.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "SMTP се користи за слање е-поште за обавештења.", "maintenance_tasks" => "Одржавање", "orphaned_logos" => "Породични логотипови", + "update" => "Ажурирај", + "new_version_available" => "Нова верзија Wallos-а је доступна", + "current_version" => "Тренутна верзија", + "latest_version" => "Најновија верзија", + "on_current_version" => "Користите најновију верзију Wallos-а.", + "show_update_notification" => "Прикажи обавештење о ажурирањима на dashboardu", // Email Verification "email_verified" => "Е-пошта је верификована", "email_verification_failed" => "Верификација е-поште није успела", diff --git a/includes/i18n/sr_lat.php b/includes/i18n/sr_lat.php index 546852e85..fd0e30afc 100644 --- a/includes/i18n/sr_lat.php +++ b/includes/i18n/sr_lat.php @@ -186,7 +186,7 @@ "theme" => "Tema", "dark_theme" => "Tamna tema", "light_theme" => "Svetla tema", - "automatic"=> "Automatski", + "automatic" => "Automatski", "main_color" => "Glavna boja", "accent_color" => "Akcentna boja", "hover_color" => "Boja prilikom prelaska", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Izračunaj i prikaži mesečnu cenu za sve pretplate", "convert_prices" => "Uvek konvertuj i prikaži cene u mojoj glavnoj valuti (sporije)", "hide_disabled_subscriptions" => "Sakrij onemogućene pretplate", + "show_disabled_subscriptions_at_the_bottom" => "Prikaži onemogućene pretplate na dnu", "experimental_settings" => "Eksperimentalna podešavanja", "remove_background" => "Pokušajte ukloniti pozadinu logotipa sa pretrage slika (eksperimentalno)", "experimental_info" => "Eksperimentalna podešavanja verovatno neće savršeno funkcionisati.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Koristiće se za oporavak lozinke i druge sistemske e-poruke.", "maintenance_tasks" => "Održavanje", "orphaned_logos" => "Nepovezani logotipi", + "update" => "Ažuriraj", + "new_version_available" => "Nova verzija Wallos-a je dostupna", + "current_version" => "Trenutna verzija", + "latest_version" => "Najnovija verzija", + "on_current_version" => "Koristite najnoviju verziju Wallos-a.", + "show_update_notification" => "Prikaži obaveštenje o ažuriranjima na dashboardu", // Email Verification "email_verified" => "E-pošta je uspešno verifikovana", "email_verification_failed" => "Verifikacija e-pošte nije uspela", diff --git a/includes/i18n/tr.php b/includes/i18n/tr.php index 952f74fcc..c589c2528 100644 --- a/includes/i18n/tr.php +++ b/includes/i18n/tr.php @@ -197,6 +197,7 @@ "calculate_monthly_price" => "Tüm aboneliklerin aylık fiyatını hesaplayın ve gösterin", "convert_prices" => "Fiyatları her zaman ana para birimimde dönüştürün ve gösterin (daha yavaş)", "hide_disabled_subscriptions" => "Devre dışı bırakılan abonelikleri gizle", + "show_disabled_subscriptions_at_the_bottom" => "Devre dışı bırakılan abonelikleri altta göster", "experimental_settings" => "Deneysel Ayarlar", "remove_background" => "Görsel aramadan logoların arka planını kaldırmayı deneyin (deneysel)", "experimental_info" => "Deneysel ayarlar muhtemelen mükemmel çalışmayacak.", @@ -309,6 +310,12 @@ "smtp_usage_info" => "Şifre kurtarma ve diğer sistem e-postaları için kullanılacaktır.", "maintenance_tasks" => "Bakım Görevleri", "orphaned_logos" => "Yetim Logolar", + "update" => "Güncelle", + "new_version_available" => "Yeni bir Wallos sürümü mevcut", + "current_version" => "Mevcut Sürüm", + "latest_version" => "En Son Sürüm", + "on_current_version" => "Wallos'un en son sürümünü kullanıyorsunuz.", + "show_update_notification" => "Gösterge panelinde güncelleme bildirimini göster", // Email Verification "email_verified" => "E-posta doğrulandı", "email_verification_failed" => "E-posta doğrulaması başarısız oldu", diff --git a/includes/i18n/zh_cn.php b/includes/i18n/zh_cn.php index 17d9514a8..3ded75a24 100644 --- a/includes/i18n/zh_cn.php +++ b/includes/i18n/zh_cn.php @@ -194,7 +194,7 @@ "theme" => "主题", "dark_theme" => "深色主题", "light_theme" => "浅色主题", - "automatic"=> "自动", + "automatic" => "自动", "main_color" => "主色", "accent_color" => "强调色", "hover_color" => "悬停颜色", @@ -205,6 +205,7 @@ "calculate_monthly_price" => "计算并显示所有订阅的月价格", "convert_prices" => "始终按我的主要货币转换和显示价格(较慢)", "hide_disabled_subscriptions" => "隐藏已停用的订阅", + "show_disabled_subscriptions_at_the_bottom" => "在订阅列表底部显示已停用的订阅", "experimental_settings" => "实验性设置", "remove_background" => "尝试从图片搜索中移除标志的背景(实验性)", "experimental_info" => "实验性设置,可能存在问题。", @@ -327,6 +328,12 @@ "smtp_usage_info" => "将用于密码恢复和其他系统电子邮件。", "maintenance_tasks" => "维护任务", "orphaned_logos" => "孤立的 Logo", + "update" => "更新", + "new_version_available" => "新的 Wallos 版本可用", + "current_version" => "当前版本", + "latest_version" => "最新版本", + "on_current_version" => "您正在运行最新版本的 Wallos。", + "show_update_notification" => "在仪表板上显示更新通知", // Email Verification "email_verified" => "电子邮件已验证", diff --git a/includes/i18n/zh_tw.php b/includes/i18n/zh_tw.php index 2c6282889..11a79223d 100644 --- a/includes/i18n/zh_tw.php +++ b/includes/i18n/zh_tw.php @@ -186,7 +186,7 @@ "theme" => "主題", "dark_theme" => "深色主題", "light_theme" => "淺色主題", - "automatic"=> "自動", + "automatic" => "自動", "main_color" => "主要顏色", "accent_color" => "強調顏色", "hover_color" => "懸停顏色", @@ -197,6 +197,7 @@ "calculate_monthly_price" => "計算並顯示所有訂閱的每月價格", "convert_prices" => "始終按照我的主要貨幣單位轉換和顯示價格(較慢)", "hide_disabled_subscriptions" => "隱藏已停用的訂閱", + "show_disabled_subscriptions_at_the_bottom" => "將已停用的訂閱顯示在底部", "experimental_settings" => "實驗性設定", "remove_background" => "嘗試從圖片搜尋中移除圖示的背景顏色(實驗性)", "experimental_info" => "實驗性設定,可能存在問題。", @@ -309,6 +310,12 @@ "smtp_usage_info" => "將用於密碼恢復和其他系統電子郵件。", "maintenance_tasks" => "維護任務", "orphaned_logos" => "孤立的圖示", + "update" => "更新", + "new_version_available" => "新的 Wallos 版本可用", + "current_version" => "當前版本", + "latest_version" => "最新版本", + "on_current_version" => "您正在運行最新版本的 Wallos。", + "show_update_notification" => "在儀表板上顯示更新通知", // Email Verification "email_verified" => "電子郵件已驗證", "email_verification_failed" => "電子郵件驗證失敗", diff --git a/includes/list_subscriptions.php b/includes/list_subscriptions.php index f37789b67..a19ab0325 100644 --- a/includes/list_subscriptions.php +++ b/includes/list_subscriptions.php @@ -49,12 +49,6 @@ function getPriceConverted($price, $currency, $database) { } function printSubscriptions($subscriptions, $sort, $categories, $members, $i18n, $colorTheme, $imagePath) { - if ($sort === "price") { - usort($subscriptions, function($a, $b) { - return $a['price'] < $b['price'] ? 1 : -1; - }); - } - $currentCategory = 0; $currentPayerUserId = 0; $currentPaymentMethodId = 0; diff --git a/includes/version.php b/includes/version.php index d7baef171..9884b3c70 100644 --- a/includes/version.php +++ b/includes/version.php @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/index.php b/index.php index a3b966dc5..0d00cd308 100644 --- a/index.php +++ b/index.php @@ -6,30 +6,51 @@ $sort = "next_payment"; $sortOrder = $sort; -$sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY next_payment ASC, inactive ASC"; + +if ($settings['disabledToBottom'] === 'true') { + $sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY inactive ASC, next_payment ASC"; +} else { + $sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY next_payment ASC, inactive ASC"; +} + if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") { - $sort = $_COOKIE['sortOrder']; + $sort = $_COOKIE['sortOrder'] ?? 'next_payment'; $sortOrder = $sort; $allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id', 'inactive', 'alphanumeric']; - $order = "ASC"; - if ($sort == "price" || $sort == "id") { - $order = "DESC"; - } + $order = ($sort == "price" || $sort == "id") ? "DESC" : "ASC"; + if ($sort == "alphanumeric") { $sort = "name"; } + if (!in_array($sort, $allowedSortCriteria)) { $sort = "next_payment"; } $sql = "SELECT * FROM subscriptions WHERE user_id = :userId"; - $sql .= " ORDER BY $sort $order"; - if ($sort != "next_payment") { - $sql .= ", next_payment ASC"; + + $orderByClauses = []; + + if ($settings['disabledToBottom'] === 'true') { + if (in_array($sort, ["payer_user_id", "category_id", "payment_method_id"])) { + $orderByClauses[] = "$sort $order"; + $orderByClauses[] = "inactive ASC"; + } else { + $orderByClauses[] = "inactive ASC"; + $orderByClauses[] = "$sort $order"; + } + } else { + $orderByClauses[] = "$sort $order"; + if ($sort != "inactive") { + $orderByClauses[] = "inactive ASC"; + } } - if ($sort != "inactive") { - $sql .= ", inactive ASC"; + + if ($sort != "next_payment") { + $orderByClauses[] = "next_payment ASC"; } + + $sql .= " ORDER BY " . implode(", ", $orderByClauses); } $stmt = $db->prepare($sql); @@ -49,7 +70,18 @@ content: ''; } +
+ +
+ : +
+ +
+
+
+ > + +
+
diff --git a/styles/dark-theme.css b/styles/dark-theme.css index 044fa5fa9..d2ca85c3e 100644 --- a/styles/dark-theme.css +++ b/styles/dark-theme.css @@ -232,4 +232,8 @@ input[type="radio"]:disabled + label::before { input { color-scheme: dark; +} + +.update-banner { + color: #FFF; } \ No newline at end of file diff --git a/styles/styles.css b/styles/styles.css index 4d40c6251..caff7e223 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -7,10 +7,13 @@ body { } body.no-scroll { - overflow-y: hidden; + overflow-y: hidden; } -input, button, select, textarea { +input, +button, +select, +textarea { font-family: Barlow, 'Helvetica Neue', Helvetica, sans-serif; font-weight: 400; } @@ -21,11 +24,12 @@ input, button, select, textarea { } } -a:hover > i { +a:hover>i { color: var(--hover-color); } -h2, h3 { +h2, +h3 { font-weight: 500; } @@ -62,7 +66,7 @@ h2, h3 { margin-right: 20px; } -.split-header > h2 .header-subtitle { +.split-header>h2 .header-subtitle { font-size: 22px; font-weight: 400; color: #666666; @@ -74,24 +78,24 @@ h2, h3 { padding: 20px 0px; } - .split-header > h2 .header-subtitle { + .split-header>h2 .header-subtitle { margin-left: 0px; font-size: 18px; } } - -body > header { + +body>header { border-bottom: 7px solid var(--main-color); background-color: white; } -body > header > .contain { +body>header>.contain { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; } - + header .logo .logo-image { height: 50px; width: 134px; @@ -130,10 +134,10 @@ header .logo .logo-image svg { cursor: pointer; -webkit-tap-highlight-color: transparent; -moz-tap-highlight-color: transparent; - -ms-tap-highlight-color: transparent; + -ms-tap-highlight-color: transparent; } -.dropbtn > img { +.dropbtn>img { width: 35px; height: 35px; object-fit: cover; @@ -180,14 +184,14 @@ header .logo .logo-image svg { } } -main > .contain { +main>.contain { display: flex; flex-direction: column; padding: 20px; } @media (max-width: 768px) { - .main > .contain { + .main>.contain { padding: 0px 10px; } } @@ -230,7 +234,7 @@ main > .contain { padding: 15px 30px; font-size: 1rem; border-radius: 8px; - transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; text-decoration: none; } @@ -273,7 +277,7 @@ button:hover svg .main-color { flex-grow: 1; } -.top-actions > .search > .search-icon { +.top-actions>.search>.search-icon { float: right; right: 15px; margin-top: -35px; @@ -283,7 +287,7 @@ button:hover svg .main-color { font-size: 20px; } -.rtl .top-actions > .search > .search-icon { +.rtl .top-actions>.search>.search-icon { float: left; right: -15px; } @@ -314,8 +318,8 @@ button:hover svg .main-color { } .subscription.inactive { - background-color: rgba(255,255,255,0.6); - color: rgba(100,100,100,0.6); + background-color: rgba(255, 255, 255, 0.6); + color: rgba(100, 100, 100, 0.6); box-shadow: 0 2px 5px rgba(100, 100, 100, 0.1); } @@ -364,7 +368,7 @@ button:hover svg .main-color { display: flex; } -.subscription-main .actions > li { +.subscription-main .actions>li { display: flex; align-items: center; justify-content: flex-start; @@ -374,15 +378,15 @@ button:hover svg .main-color { border-bottom: 1px solid #eee; } -.subscription-main .actions > li:hover { +.subscription-main .actions>li:hover { background-color: #f9f9f9; } -.subscription-main .actions > li > i { +.subscription-main .actions>li>i { color: var(--main-color); } -.subscription-main .actions > li:hover > i { +.subscription-main .actions>li:hover>i { color: var(--hover-color); } @@ -413,8 +417,8 @@ button:hover svg .main-color { height: 20px; } -.subscription-main > span, -.subscription-secondary > span { +.subscription-main>span, +.subscription-secondary>span { display: flex; align-items: center; justify-content: center; @@ -484,30 +488,30 @@ button:hover svg .main-color { cursor: pointer; } -.subscription-secondary > .name { +.subscription-secondary>.name { display: none; justify-content: flex-start; flex-basis: 33%; } -.subscription-secondary > span { +.subscription-secondary>span { justify-content: flex-start; flex-basis: 33%; gap: 10px; } -.subscription-secondary > .url { +.subscription-secondary>.url { flex-basis: 20px; margin-left: auto; cursor: pointer; } -.rtl .subscription-secondary > .url { +.rtl .subscription-secondary>.url { margin-left: 0px; margin-right: auto; } -.subscription-notes > span { +.subscription-notes>span { display: flex; align-items: center; font-size: 14px; @@ -515,15 +519,15 @@ button:hover svg .main-color { } @media (max-width: 768px) { - .subscription-main > .name { + .subscription-main>.name { display: none; } - .subscription-secondary > .name { + .subscription-secondary>.name { display: flex; } - .subscription-secondary > span { + .subscription-secondary>span { flex-grow: 1; flex-shrink: 1; font-size: 14px; @@ -531,7 +535,7 @@ button:hover svg .main-color { } @media (max-width: 375px) { - .subscription-main > .cycle { + .subscription-main>.cycle { display: none; } } @@ -547,7 +551,8 @@ button:hover svg .main-color { } .subscription-secondary .url img { - margin-right: 0px;; + margin-right: 0px; + ; } .empty-page, @@ -559,25 +564,25 @@ button:hover svg .main-color { font-size: 20px; } -.empty-page > img, -.no-matching-subscriptions > img { +.empty-page>img, +.no-matching-subscriptions>img { max-width: 100%; } -.no-matching-subscriptions > img { +.no-matching-subscriptions>img { margin-top: 30px; } -.empty-page > p { +.empty-page>p { margin: 5px 0px 40px 0px; } -.no-matching-subscriptions > p { +.no-matching-subscriptions>p { margin: 30px 0px 40px 0px; } -.empty-page > button, -.no-matching-subscriptions > button { +.empty-page>button, +.no-matching-subscriptions>button { margin: 0px auto; } @@ -595,10 +600,10 @@ button:hover svg .main-color { } .account-section header h2.second-header { - margin-top:34px; + margin-top: 34px; } -.account-section + .account-section { +.account-section+.account-section { margin-top: 34px; } @@ -629,9 +634,9 @@ button:hover svg .main-color { @media (max-width: 768px) { .user-form .fields { - flex-direction: column; - align-items: center; - gap: 20px; + flex-direction: column; + align-items: center; + gap: 20px; } .grow { @@ -640,14 +645,14 @@ button:hover svg .main-color { } header #avatar { - border-radius: 50%; + border-radius: 50%; } .user-form .user-avatar { position: relative; } -.user-form .user-avatar > img { +.user-form .user-avatar>img { cursor: pointer; width: 80px; height: 80px; @@ -659,27 +664,27 @@ header #avatar { } .user-form .user-avatar .edit-avatar { - display: none; - align-items: center; - justify-content: center; - width: 80px; - height: 80px; - position: absolute; - top: 0px; - left: 0px; - background-color: rgba(0,0,0,0.6); - border-radius: 39px; - cursor: pointer; - color: #FFFFFF; - font-size: 30px; + display: none; + align-items: center; + justify-content: center; + width: 80px; + height: 80px; + position: absolute; + top: 0px; + left: 0px; + background-color: rgba(0, 0, 0, 0.6); + border-radius: 39px; + cursor: pointer; + color: #FFFFFF; + font-size: 30px; } -.user-form .user-avatar:hover > .edit-avatar { +.user-form .user-avatar:hover>.edit-avatar { display: flex; } @media (max-width: 768px) { - .user-form .user-avatar:hover > .edit-avatar { + .user-form .user-avatar:hover>.edit-avatar { display: none; } } @@ -698,7 +703,7 @@ header #avatar { } .avatar-option { - border-radius: 50%; + border-radius: 50%; } @media (max-width: 768px) { @@ -718,8 +723,8 @@ header #avatar { flex-wrap: wrap; } -.avatar-select .avatar-list > img, -.avatar-select .avatar-list .avatar-container > img { +.avatar-select .avatar-list>img, +.avatar-select .avatar-list .avatar-container>img { width: 60px; height: 60px; object-fit: cover; @@ -728,8 +733,8 @@ header #avatar { box-sizing: border-box } -.avatar-select .avatar-list > img:hover, -.avatar-select .avatar-list .avatar-container > img:hover { +.avatar-select .avatar-list>img:hover, +.avatar-select .avatar-list .avatar-container>img:hover { border: 1px solid #222; } @@ -786,7 +791,7 @@ header #avatar { .user-form .buttons, .account-members .buttons, -.account-currencies .buttons, +.account-currencies .buttons, .account-fixer .buttons, .account-categories .buttons, .account-notifications .buttons, @@ -807,8 +812,8 @@ header #avatar { .account-notifications-section { border: 1px solid #ccc; border-radius: 8px; - margin-bottom: 10px; - overflow: hidden; + margin-bottom: 10px; + overflow: hidden; } .account-notification-section-header { @@ -830,20 +835,23 @@ header #avatar { .account-notification-section-settings { max-height: 0px; - overflow: hidden; /* Hide content that goes beyond the height */ - transition: max-height 0.3s ease-in-out; /* Animate max-height changes */ + overflow: hidden; + /* Hide content that goes beyond the height */ + transition: max-height 0.3s ease-in-out; + /* Animate max-height changes */ padding: 0px 16px; } .account-notification-section-settings.is-open { - max-height: 1000px; /* Set to a value larger than the content's natural height */ + max-height: 1000px; + /* Set to a value larger than the content's natural height */ } -.account-notification-section-settings > div:first-of-type { +.account-notification-section-settings>div:first-of-type { margin-top: 20px; } -.account-notification-section-settings > div:last-of-type { +.account-notification-section-settings>div:last-of-type { margin-bottom: 20px; } @@ -859,38 +867,38 @@ header #avatar { padding: 0px; } -.image-button > i { +.image-button>i { color: var(--hover-color); font-size: 28px; padding: 2px; } -.image-button > svg { +.image-button>svg { width: 32px; height: 32px; } -.image-button.disabled > img, -.image-button.disabled > svg { +.image-button.disabled>img, +.image-button.disabled>svg { -webkit-filter: grayscale(100%); filter: grayscale(100%); } -.image-button.success > img { +.image-button.success>img { filter: hue-rotate(262deg); } -.image-button.error > img { +.image-button.error>img { filter: hue-rotate(141deg); } -.image-button.small > img { +.image-button.small>img { width: 25px; height: 25px; object-fit: contain; } -.image-button.medium > img { +.image-button.medium>img { width: 32px; height: 32px; object-fit: contain; @@ -928,13 +936,13 @@ header #avatar { font-size: 14px; } -.payments-list .payments-payment > img { +.payments-list .payments-payment>img { width: 32px; height: 32px; object-fit: contain; } -.payments-list .payments-payment > .payment-name { +.payments-list .payments-payment>.payment-name { cursor: text; } @@ -951,58 +959,67 @@ header #avatar { line-break: anywhere; } -.credits-list > p { +.credits-list>p { margin: 0px; font-size: 18px; } +.updates-list>p { + margin: 0px; +} + .settings-notes { margin-bottom: 1.5em; } -.settings-notes > p { +.settings-notes>p { margin-bottom: 0px; } -.credits-list > p > span, -.settings-notes > p > span { +.credits-list>p>span, +.updates-list>p>span, +.settings-notes>p>span { color: #AAA; font-size: 14px; } -.credits-list > p > span { +.credits-list>p>span, +.updates-list>p>span { font-size: 16px; } -.credits-list > p > span > a, -.settings-notes > p > span > a { +.credits-list>p>span>a, +.updates-list>p>span>a, +.settings-notes>p>span>a { margin-left: 5px; font-size: 13px; color: var(--accent-color); } -.rtl .credits-list > p > span > a, -.rtl .settings-notes > p > span > a { +.rtl .credits-list>p>span>a, +.rtl .updates-list>p>span>a, +.rtl .settings-notes>p>span>a { margin-left: 0px; margin-right: 5px; } -.credits-list > p > span > a:visited, -.settings-notes > p > span > a:visited { +.credits-list>p>span>a:visited, +.updates-list>p>span>a:visited, +.settings-notes>p>span>a:visited { color: var(--accent-color); } -.settings-notes > p > i, -.account-section .notes > p > i { +.settings-notes>p>i, +.account-section .notes>p>i { color: var(--main-color); margin-right: 5px; -} +} -.rtl .settings-notes > p > i, -.rtl .account-section .notes > p > i { +.rtl .settings-notes>p>i, +.rtl .account-section .notes>p>i { margin-right: 0px; margin-left: 5px; -} +} .form-group { margin-bottom: 20px; @@ -1087,7 +1104,7 @@ input[type="color"] { width: 46px; background-color: #222; border: 1px solid var(--hover-color); - outline: none; + outline: none; box-sizing: border-box; cursor: pointer; font-size: 16px; @@ -1178,8 +1195,7 @@ button.button:disabled { border-color: #ccc; } -input[type="button"].left -button.button.left { +input[type="button"].left button.button.left { margin-right: auto; } @@ -1227,9 +1243,9 @@ textarea.thin { @media (max-width: 768px) { input[type="checkbox"] { - width: 20px; - height: 20px; - flex-shrink: 0; + width: 20px; + height: 20px; + flex-shrink: 0; } } @@ -1267,8 +1283,8 @@ textarea.thin { display: block; } -.logo-search > header, -.icon-search > header { +.logo-search>header, +.icon-search>header { padding: 0px 5px 5px; border-bottom: 1px solid #CCC; display: flex; @@ -1277,7 +1293,7 @@ textarea.thin { margin-bottom: 10px; } -.icon-search > header > span { +.icon-search>header>span { margin-left: auto; } @@ -1352,7 +1368,7 @@ button.dark-theme-button i { display: none; } -.user-error.show, +.user-error.show, .user-success.show { display: block; } @@ -1399,6 +1415,7 @@ button.dark-theme-button i { } @media (max-width: 768px) { + .subscription-form, .subscription-modal { width: 100%; @@ -1406,7 +1423,7 @@ button.dark-theme-button i { } .subscription-form .buttons input { - flex: 1; + flex: 1; } } @@ -1529,12 +1546,12 @@ button.dark-theme-button i { display: block; } -.sort-options > ul { +.sort-options>ul { padding: 0px; margin: 0px; } -.sort-options > ul > li { +.sort-options>ul>li { position: relative; list-style: none; padding: 14px 35px 14px 18px; @@ -1542,19 +1559,19 @@ button.dark-theme-button i { cursor: pointer; } -.rtl .sort-options > ul > li { +.rtl .sort-options>ul>li { padding: 14px 18px 14px 35px; } -.sort-options > ul > li:last-of-type { +.sort-options>ul>li:last-of-type { border-bottom: none; } -.sort-options > ul > li:hover { +.sort-options>ul>li:hover { background-color: #EEE; } -.sort-options > ul > li.selected::after { +.sort-options>ul>li.selected::after { content: ""; position: absolute; right: 10px; @@ -1568,7 +1585,7 @@ button.dark-theme-button i { background-size: 100% 100%; } -.rtl .sort-options > ul > li.selected { +.rtl .sort-options>ul>li.selected { background-position: center left 10px; } @@ -1745,24 +1762,24 @@ button.dark-theme-button i { } } -.statistic > span { +.statistic>span { font-size: 42px; - color: var(--main-color); + color: var(--main-color); } -.statistic > .title { +.statistic>.title { margin-top: 5px; text-align: center; } -.statistic > .subtitle { +.statistic>.subtitle { font-size: 25px; color: var(--accent-color); margin-top: 10px; text-align: center; } -.statistic > .subtitle > img { +.statistic>.subtitle>img { width: 100px; max-height: 40px; object-fit: contain; @@ -1790,14 +1807,14 @@ button.dark-theme-button i { box-sizing: border-box; } -.graph > header { +.graph>header { font-size: 18px; font-weight: 500; margin-bottom: 15px; text-align: center; } -.graph > header > .sub-header { +.graph>header>.sub-header { font-size: 13px; font-weight: normal; } @@ -1850,7 +1867,7 @@ button.dark-theme-button i { display: none; position: absolute; background-color: #f9f9f9; - left: auto; + left: auto; right: 0; width: 220px; background-color: #fff; @@ -1921,12 +1938,16 @@ button.dark-theme-button i { right: 10px; top: 50%; transform: translateY(-50%); - width: 16px; /* Explicitly set the size */ - height: 16px; /* Explicitly set the size */ - background-color: var(--main-color); /* Set your desired color here */ + width: 16px; + /* Explicitly set the size */ + height: 16px; + /* Explicitly set the size */ + background-color: var(--main-color); + /* Set your desired color here */ -webkit-mask: url("../images/siteicons/svg/check.php") no-repeat center; mask: url("../images/siteicons/svg/check.php") no-repeat center; - background-size: 100% 100%; /* Ensure the icon scales correctly */ + background-size: 100% 100%; + /* Ensure the icon scales correctly */ } .rtl .filtermenu-content .filter-item.selected { @@ -1939,11 +1960,11 @@ button.dark-theme-button i { border-bottom: none; } -.filtermenu-content .filter-title.filter-clear > i { +.filtermenu-content .filter-title.filter-clear>i { margin-right: 8px; } -.rtl .filtermenu-content .filter-title.filter-clear > i { +.rtl .filtermenu-content .filter-title.filter-clear>i { margin-left: 8px; margin-right: 0px; } @@ -2092,7 +2113,7 @@ button.dark-theme-button i { justify-content: space-between; } -.user-list > div { +.user-list>div { display: flex; flex-direction: row; flex-grow: 1; @@ -2106,7 +2127,7 @@ button.dark-theme-button i { } @media (max-width: 768px) { - .user-list .user-list-row { + .user-list .user-list-row { flex-direction: column; } } @@ -2115,7 +2136,7 @@ button.dark-theme-button i { flex-grow: 0; } -.user-list .user-list-row > div { +.user-list .user-list-row>div { display: flex; flex-basis: 50%; gap: 12px; @@ -2285,7 +2306,7 @@ input[type="checkbox"] { position: absolute; } -input[type="checkbox"] + label { +input[type="checkbox"]+label { position: relative; padding-left: 35px; cursor: pointer; @@ -2293,7 +2314,7 @@ input[type="checkbox"] + label { line-height: 22px; } -input[type="checkbox"] + label::before { +input[type="checkbox"]+label::before { content: ''; position: absolute; left: 0; @@ -2305,18 +2326,18 @@ input[type="checkbox"] + label::before { border-radius: 3px; } -input[type="checkbox"]:focus + label::before { +input[type="checkbox"]:focus+label::before { border-color: var(--main-color); - box-shadow: 0 0 0 2px rgba(--main-color-rgb,0.5); + box-shadow: 0 0 0 2px rgba(--main-color-rgb, 0.5); } -input[type="checkbox"]:disabled + label::before { +input[type="checkbox"]:disabled+label::before { background-color: #F5F5F5; border-color: #F5F5F5; cursor: not-allowed; } -input[type="checkbox"]:checked + label::after { +input[type="checkbox"]:checked+label::after { content: ''; position: absolute; left: 8px; @@ -2334,7 +2355,7 @@ input[type="radio"] { position: absolute; } -input[type="radio"] + label { +input[type="radio"]+label { position: relative; padding-left: 35px; cursor: pointer; @@ -2342,7 +2363,7 @@ input[type="radio"] + label { line-height: 22px; } -input[type="radio"] + label::before { +input[type="radio"]+label::before { content: ''; position: absolute; left: 0; @@ -2355,18 +2376,18 @@ input[type="radio"] + label::before { box-sizing: border-box; } -input[type="radio"]:focus + label::before { +input[type="radio"]:focus+label::before { border-color: var(--main-color); - box-shadow: 0 0 0 2px rgba(var(--main-color-rgb),0.5); + box-shadow: 0 0 0 2px rgba(var(--main-color-rgb), 0.5); } -input[type="radio"]:disabled + label::before { +input[type="radio"]:disabled+label::before { background-color: #F5F5F5; border-color: #F5F5F5; cursor: not-allowed; } -input[type="radio"]:checked + label::after { +input[type="radio"]:checked+label::after { content: ''; position: absolute; left: 5px; @@ -2378,16 +2399,30 @@ input[type="radio"]:checked + label::after { box-sizing: border-box; } -.theme input[type="radio"] + label { +.theme input[type="radio"]+label { padding-left: 44px; } -.theme input[type="radio"] + label::before { +.theme input[type="radio"]+label::before { left: 11px; top: 20px; } -.theme input[type="radio"]:checked + label::after { +.theme input[type="radio"]:checked+label::after { left: 16px; top: 25px; +} + +.update-banner { + padding: 15px 20px; + background-color: var(--accent-color); + border: 1px solid var(--main-color); + border-radius: 12px; + margin-bottom: 20px; + text-align: center; + color: #222; +} + +.update-banner > span { + font-weight: 500; } \ No newline at end of file