Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f5e69a17d |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.1 (2026-01-30)
|
||||||
|
|
||||||
|
### GUI
|
||||||
|
|
||||||
|
- **dialogs/about.py** - Dialog "O programu" zobrazující název, verzi, autora a popis. Červený DEV badge pokud je aktivní vývojářský režim (ENV_DEBUG)
|
||||||
|
- **tray_app.py** - Položka "O programu..." v tray menu
|
||||||
|
|
||||||
|
### Interní
|
||||||
|
|
||||||
|
- **version.py** - Modul pro získání verze z pyproject.toml s fallbackem do _version.py
|
||||||
|
- **_version.py** - Automaticky aktualizovaný fallback soubor s poslední známou verzí
|
||||||
|
|
||||||
## 1.0.0 (2026-01-30)
|
## 1.0.0 (2026-01-30)
|
||||||
|
|
||||||
První kompletní verze aplikace Vault.
|
První kompletní verze aplikace Vault.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "vault"
|
name = "vault"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
description = ""
|
description = ""
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Jan Doubravský",email = "jan.doubravsky@gmail.com"}
|
{name = "Jan Doubravský",email = "jan.doubravsky@gmail.com"}
|
||||||
|
|||||||
1
src/_version.py
Normal file
1
src/_version.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
__version__ = "1.0.1"
|
||||||
73
src/ui/dialogs/about.py
Normal file
73
src/ui/dialogs/about.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
"""About program dialog."""
|
||||||
|
|
||||||
|
from PySide6.QtCore import Qt
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QDialog,
|
||||||
|
QHBoxLayout,
|
||||||
|
QLabel,
|
||||||
|
QPushButton,
|
||||||
|
QVBoxLayout,
|
||||||
|
QWidget,
|
||||||
|
)
|
||||||
|
|
||||||
|
from src.version import get_version, is_dev
|
||||||
|
|
||||||
|
|
||||||
|
class AboutDialog(QDialog):
|
||||||
|
"""Dialog showing program information."""
|
||||||
|
|
||||||
|
def __init__(self, parent: QWidget | None = None) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle("O programu")
|
||||||
|
self.setFixedWidth(360)
|
||||||
|
self._setup_ui()
|
||||||
|
|
||||||
|
def _setup_ui(self) -> None:
|
||||||
|
"""Set up dialog UI."""
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.setSpacing(12)
|
||||||
|
|
||||||
|
# App name
|
||||||
|
name_label = QLabel("Vault")
|
||||||
|
name_label.setStyleSheet("font-size: 22px; font-weight: bold;")
|
||||||
|
name_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
layout.addWidget(name_label)
|
||||||
|
|
||||||
|
# Version row
|
||||||
|
version = get_version()
|
||||||
|
version_text = f"Verze {version}"
|
||||||
|
if is_dev():
|
||||||
|
version_text += ' <span style="color: #e74c3c; font-weight: bold;">DEV</span>'
|
||||||
|
|
||||||
|
version_label = QLabel(version_text)
|
||||||
|
version_label.setTextFormat(Qt.TextFormat.RichText)
|
||||||
|
version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
version_label.setStyleSheet("font-size: 13px; color: #888;")
|
||||||
|
layout.addWidget(version_label)
|
||||||
|
|
||||||
|
layout.addSpacing(8)
|
||||||
|
|
||||||
|
# Description
|
||||||
|
desc_label = QLabel("Bezpečné úložiště souborů s podporou replik\na automatické synchronizace.")
|
||||||
|
desc_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
desc_label.setWordWrap(True)
|
||||||
|
layout.addWidget(desc_label)
|
||||||
|
|
||||||
|
layout.addSpacing(4)
|
||||||
|
|
||||||
|
# Author
|
||||||
|
author_label = QLabel("Autor: Jan Doubravský")
|
||||||
|
author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
author_label.setStyleSheet("font-size: 11px; color: #aaa;")
|
||||||
|
layout.addWidget(author_label)
|
||||||
|
|
||||||
|
layout.addStretch()
|
||||||
|
|
||||||
|
# Close button
|
||||||
|
btn_layout = QHBoxLayout()
|
||||||
|
btn_layout.addStretch()
|
||||||
|
close_btn = QPushButton("Zavřít")
|
||||||
|
close_btn.clicked.connect(self.accept)
|
||||||
|
btn_layout.addWidget(close_btn)
|
||||||
|
btn_layout.addStretch()
|
||||||
|
layout.addLayout(btn_layout)
|
||||||
@@ -117,6 +117,9 @@ class VaultTrayApp:
|
|||||||
|
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
|
# About
|
||||||
|
menu.addAction("O programu...").triggered.connect(self._show_about)
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
menu.addAction("Ukončit").triggered.connect(self._quit)
|
menu.addAction("Ukončit").triggered.connect(self._quit)
|
||||||
|
|
||||||
@@ -362,6 +365,13 @@ class VaultTrayApp:
|
|||||||
logger.error(f"Resize failed: {e}")
|
logger.error(f"Resize failed: {e}")
|
||||||
self._notifications.notify("Chyba", f"Nepodařilo se zvětšit vault: {e}", critical=True)
|
self._notifications.notify("Chyba", f"Nepodařilo se zvětšit vault: {e}", critical=True)
|
||||||
|
|
||||||
|
def _show_about(self) -> None:
|
||||||
|
"""Show about dialog."""
|
||||||
|
from src.ui.dialogs.about import AboutDialog
|
||||||
|
|
||||||
|
dialog = AboutDialog()
|
||||||
|
dialog.exec()
|
||||||
|
|
||||||
def _quit(self) -> None:
|
def _quit(self) -> None:
|
||||||
"""Quit the application."""
|
"""Quit the application."""
|
||||||
if self._vault.is_open:
|
if self._vault.is_open:
|
||||||
|
|||||||
59
src/version.py
Normal file
59
src/version.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tomllib
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
_ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
load_dotenv(_ROOT / ".env")
|
||||||
|
|
||||||
|
|
||||||
|
def _project_root() -> Path:
|
||||||
|
"""Return the project root directory (where pyproject.toml lives)."""
|
||||||
|
return Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
def get_version() -> str:
|
||||||
|
"""Get the current version string.
|
||||||
|
|
||||||
|
Reads from pyproject.toml if available and updates the fallback
|
||||||
|
``_version.py``. Falls back to ``_version.py`` when the toml file
|
||||||
|
is not present (e.g. in a packaged distribution).
|
||||||
|
"""
|
||||||
|
toml_path = _project_root() / "pyproject.toml"
|
||||||
|
|
||||||
|
if toml_path.is_file():
|
||||||
|
try:
|
||||||
|
with open(toml_path, "rb") as f:
|
||||||
|
data = tomllib.load(f)
|
||||||
|
version = data["tool"]["poetry"]["version"]
|
||||||
|
_update_fallback(version)
|
||||||
|
return version
|
||||||
|
except Exception:
|
||||||
|
logger.debug("Failed to read version from pyproject.toml, using fallback")
|
||||||
|
|
||||||
|
# Fallback
|
||||||
|
from src._version import __version__
|
||||||
|
return __version__
|
||||||
|
|
||||||
|
|
||||||
|
def _update_fallback(version: str) -> None:
|
||||||
|
"""Write the version to ``_version.py`` so it's available even without toml."""
|
||||||
|
fallback_path = Path(__file__).resolve().parent / "_version.py"
|
||||||
|
try:
|
||||||
|
new_content = f'__version__ = "{version}"\n'
|
||||||
|
# Only write if changed
|
||||||
|
if fallback_path.is_file() and fallback_path.read_text() == new_content:
|
||||||
|
return
|
||||||
|
fallback_path.write_text(new_content)
|
||||||
|
except Exception:
|
||||||
|
logger.debug("Failed to update _version.py fallback")
|
||||||
|
|
||||||
|
|
||||||
|
def is_dev() -> bool:
|
||||||
|
"""Return True if running in development mode (ENV_DEBUG is set)."""
|
||||||
|
return os.getenv("ENV_DEBUG", "").strip().lower() == "true"
|
||||||
Reference in New Issue
Block a user