Built site for gh-pages (5e5bd09)

This commit is contained in:
gitea-actions committed 2026-08-13 17:07:40 +00:00
1 parent 40ea4819a0
commit d96a3d19bc
5 files changed
+900

No files matched your search

+6
View File
@@ -134,6 +134,12 @@ ul.task-list li input[type="checkbox"] {
<a href="./navody/immich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Immich</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="./navody/ledrich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Ledriche</span></a>
</div>
</li>
</ul>
</li>
+6
View File
@@ -132,6 +132,12 @@ ul.task-list li input[type="checkbox"] {
<a href="./navody/immich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Immich</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="./navody/ledrich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Ledriche</span></a>
</div>
</li>
</ul>
</li>
+6
View File
@@ -134,6 +134,12 @@ ul.task-list li input[type="checkbox"] {
<a href="../navody/immich.html" class="sidebar-item-text sidebar-link active">
<span class="menu-text">Návod na používání Immich</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../navody/ledrich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Ledriche</span></a>
</div>
</li>
</ul>
</li>
+794
View File
@@ -0,0 +1,794 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.10.18">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<meta name="author" content="David Spáčil">
<meta name="dcterms.date" content="2026-08-11">
<title>Návod na používání Ledriche – Nápověda</title>
<style>
/* Default styles provided by pandoc.
** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
*/
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: 1.5em;}
div.column{flex: auto;}
@media screen {
div.columns{gap: min(4vw, 1.5em);}
div.column{overflow-x: auto;}
}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
width: 0.8em;
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
vertical-align: middle;
}
</style>
<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
<script src="../site_libs/quarto-nav/headroom.min.js"></script>
<script src="../site_libs/clipboard/clipboard.min.js"></script>
<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
<script src="../site_libs/quarto-search/fuse.min.js"></script>
<script src="../site_libs/quarto-search/quarto-search.js"></script>
<meta name="quarto:offset" content="../">
<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../site_libs/quarto-html/popper.min.js"></script>
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../site_libs/quarto-html/anchor.min.js"></script>
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-64a204ab8560d761af7679ceaba22944.css" rel="stylesheet" id="quarto-text-highlighting-styles">
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../site_libs/bootstrap/bootstrap-904f0f42f600c2f12b01f8e17a75384f.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
"location": "sidebar",
"copy-button": false,
"collapse-after": 3,
"panel-placement": "start",
"type": "textbox",
"limit": 50,
"keyboard-shortcut": [
"f",
"/",
"s"
],
"show-item-context": false,
"language": {
"search-no-results-text": "No results",
"search-matching-documents-text": "matching documents",
"search-copy-link-title": "Copy link to search",
"search-hide-matches-text": "Hide additional matches",
"search-more-match-text": "more match in this document",
"search-more-matches-text": "more matches in this document",
"search-clear-button-title": "Clear",
"search-text-placeholder": "",
"search-detached-cancel-button-title": "Cancel",
"search-submit-button-title": "Submit",
"search-label": "Search"
}
}</script>
<link rel="stylesheet" href="../styles.css">
</head>
<body class="nav-sidebar docked quarto-light">
<div id="quarto-search-results"></div>
<header id="quarto-header" class="headroom fixed-top">
<nav class="quarto-secondary-nav">
<div class="container-fluid d-flex">
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" role="button" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
<i class="bi bi-layout-text-sidebar-reverse"></i>
</button>
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="../navody/immich.html">Návody</a></li><li class="breadcrumb-item"><a href="../navody/ledrich.html">Návod na používání Ledriche</a></li></ol></nav>
<a class="flex-grow-1" role="navigation" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
</a>
<button type="button" class="btn quarto-search-button" aria-label="Search" onclick="window.quartoOpenSearch();">
<i class="bi bi-search"></i>
</button>
</div>
</nav>
</header>
<!-- content -->
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
<!-- sidebar -->
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation docked overflow-auto">
<div class="pt-lg-2 mt-2 text-left sidebar-header">
<div class="sidebar-title mb-0 py-0">
<a href="../">Nápověda</a>
</div>
</div>
<div class="mt-2 flex-shrink-0 align-items-center">
<div class="sidebar-search">
<div id="quarto-search" class="" title="Search"></div>
</div>
</div>
<div class="sidebar-menu-container">
<ul class="list-unstyled mt-1">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../index.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Home</span></a>
</div>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" role="navigation" aria-expanded="true">
<span class="menu-text">Návody</span></a>
<a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" role="navigation" aria-expanded="true" aria-label="Toggle section">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-1" class="collapse list-unstyled sidebar-section depth1 show">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../navody/immich.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Návod na používání Immich</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../navody/ledrich.html" class="sidebar-item-text sidebar-link active">
<span class="menu-text">Návod na používání Ledriche</span></a>
</div>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
<!-- margin-sidebar -->
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
<nav id="TOC" role="doc-toc" class="toc-active">
<h2 id="toc-title">On this page</h2>
<ul>
<li><a href="#přihlášení" id="toc-přihlášení" class="nav-link active" data-scroll-target="#přihlášení">Přihlášení</a></li>
<li><a href="#orientace-v-prostředí" id="toc-orientace-v-prostředí" class="nav-link" data-scroll-target="#orientace-v-prostředí">Orientace v prostředí</a></li>
<li><a href="#přidání-výdaje" id="toc-přidání-výdaje" class="nav-link" data-scroll-target="#přidání-výdaje">Přidání výdaje</a>
<ul class="collapse">
<li><a href="#jak-se-výdaj-dělí" id="toc-jak-se-výdaj-dělí" class="nav-link" data-scroll-target="#jak-se-výdaj-dělí">Jak se výdaj dělí</a></li>
<li><a href="#zopakování-výdaje" id="toc-zopakování-výdaje" class="nav-link" data-scroll-target="#zopakování-výdaje">Zopakování výdaje</a></li>
<li><a href="#oprava-a-smazání" id="toc-oprava-a-smazání" class="nav-link" data-scroll-target="#oprava-a-smazání">Oprava a smazání</a></li>
</ul></li>
<li><a href="#dluh-a-vyrovnání" id="toc-dluh-a-vyrovnání" class="nav-link" data-scroll-target="#dluh-a-vyrovnání">Dluh a vyrovnání</a></li>
<li><a href="#statistiky" id="toc-statistiky" class="nav-link" data-scroll-target="#statistiky">Statistiky</a></li>
<li><a href="#nastavení" id="toc-nastavení" class="nav-link" data-scroll-target="#nastavení">Nastavení</a>
<ul class="collapse">
<li><a href="#přidání-účastníka" id="toc-přidání-účastníka" class="nav-link" data-scroll-target="#přidání-účastníka">Přidání účastníka</a></li>
<li><a href="#odebrání-účastníka-archivace" id="toc-odebrání-účastníka-archivace" class="nav-link" data-scroll-target="#odebrání-účastníka-archivace">Odebrání účastníka: archivace</a></li>
</ul></li>
<li><a href="#co-s-daty" id="toc-co-s-daty" class="nav-link" data-scroll-target="#co-s-daty">Co s daty</a></li>
</ul>
<div class="toc-actions"><ul><li><a href="https://gitea.spacilovi.eu/david-spacil/help/issues/new" class="toc-action"><i class="bi bi-git"></i>Report an issue</a></li></ul></div></nav>
</div>
<!-- main -->
<main class="content" id="quarto-document-content">
<header id="title-block-header" class="quarto-title-block default"><nav class="quarto-page-breadcrumbs quarto-title-breadcrumbs d-none d-lg-block" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="../navody/immich.html">Návody</a></li><li class="breadcrumb-item"><a href="../navody/ledrich.html">Návod na používání Ledriche</a></li></ol></nav>
<div class="quarto-title">
<h1 class="title">Návod na používání Ledriche</h1>
</div>
<div class="quarto-title-meta">
<div>
<div class="quarto-title-meta-heading">Author</div>
<div class="quarto-title-meta-contents">
<p>David Spáčil </p>
</div>
</div>
<div>
<div class="quarto-title-meta-heading">Published</div>
<div class="quarto-title-meta-contents">
<p class="date">August 11, 2026</p>
</div>
</div>
</div>
</header>
<p>Ledrich je aplikace na evidenci společných výdajů a dělení nákladů – tedy na situace, kdy se skládá víc lidí a nikomu se nechce vést papírové poznámky o tom, kdo co zaplatil a komu kolik dluží. Funguje podobně jako známé appky typu Splitwise nebo Tricount, ale běží na našem vlastním serveru, takže data o tom, za co utrácíme, nikam ven neodcházejí. Používá se hlavně z mobilu – aplikace je udělaná tak, aby se výdaj dal zadat jednou rukou cestou z obchodu.</p>
<p>Vede se v ní <strong>kniha</strong>: seznam účastníků, kteří se o výdaje dělí, a všechny jejich platby.</p>
<section id="přihlášení" class="level2">
<h2 class="anchored" data-anchor-id="přihlášení">Přihlášení</h2>
<p>Registrace není možná, účty zakládá správce knihy. Když se má někdo přidat, správce ho přidá v <code>Nastavení</code> a předá mu heslo.</p>
<p>Na přihlašovací obrazovce se vybere jméno ze seznamu a zadá heslo. Po přihlášení zůstáváte přihlášení dlouhodobě, takže se na mobilu heslo zadává jen výjimečně.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Tip
</div>
</div>
<div class="callout-body-container callout-body">
<p>Aplikaci si na mobilu můžete přidat na plochu (v prohlížeči <em>Přidat na plochu</em> / <em>Add to Home Screen</em>). Pak se otevírá jako běžná appka, na celou obrazovku a bez adresního řádku.</p>
</div>
</div>
<p>Pokud po zadání hesla obrazovka „probliknutím“ spadne zpátky na přihlášení, aplikace vám sama napíše proč – nejčastěji je to tím, že se k ní jde přes nezabezpečené spojení.</p>
</section>
<section id="orientace-v-prostředí" class="level2">
<h2 class="anchored" data-anchor-id="orientace-v-prostředí">Orientace v prostředí</h2>
<p>Dole jsou tři záložky a nad nimi oranžové kolečko s plusem.</p>
<ul>
<li><code>Platby</code> – seznam všech výdajů, od nejnovějšího. Klepnutím na výdaj se otevře k úpravě.</li>
<li><code>Dluh</code> – kdo komu kolik dluží a tlačítko na vyrovnání.</li>
<li><code>Statistiky</code> – souhrnná čísla, graf v čase a rozpady.</li>
<li><strong>Oranžové tlačítko <code>+</code></strong> – přidání výdaje. Je záměrně mimo záložky a nad nimi, protože je to jediná činnost, kvůli které se aplikace otevírá venku, a musí být na dosah palce.</li>
</ul>
<p>Oranžová barva patří v celé aplikaci jen tomuhle tlačítku, takže je vždycky jasné, kam sáhnout.</p>
<p>Nahoře je název knihy a vedle něj <code>Nastavení</code> a <code>Odhlásit</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Když v hlavičce občas problikne informace o čekajících změnách, znamená to, že byl výpadek spojení se serverem. <strong>Nic se neztratilo</strong> – zadané výdaje jsou uložené a odešlou se samy, jakmile se spojení vrátí.</p>
</div>
</div>
</section>
<section id="přidání-výdaje" class="level2">
<h2 class="anchored" data-anchor-id="přidání-výdaje">Přidání výdaje</h2>
<p>Klepnutím na oranžové <code>+</code> se otevře formulář. Vyplňuje se:</p>
<ul>
<li><strong>Částka</strong> – hlavní pole, samo se zaostří. Zadává se v korunách, haléře se dají zapsat za desetinnou čárkou.</li>
<li><strong>Za co</strong> – krátký popis, např. <em>nákup Lidl</em>.</li>
<li><strong>Kdo platil</strong> – ten, kdo peníze skutečně vytáhl z kapsy. Není to totéž jako to, koho výdaj stál (viz dělení níž).</li>
<li><strong>Datum</strong> – předvyplněné na dnešek.</li>
<li><strong>Jak se to dělí</strong> – viz další sekce.</li>
<li><strong>Štítky</strong> – nepovinné, slouží k roztřídění výdajů. Nabízejí se dřív použité, nový se prostě napíše.</li>
<li><strong>Poznámka</strong> – nepovinná, na cokoli, co se nevejde do popisu.</li>
</ul>
<p>Uloží se tlačítkem <code>Přidat výdaj</code>.</p>
<section id="jak-se-výdaj-dělí" class="level3">
<h3 class="anchored" data-anchor-id="jak-se-výdaj-dělí">Jak se výdaj dělí</h3>
<p>Tohle je jádro celé aplikace. Pod formulářem je <strong>dělicí pruh</strong> – vodorovný proužek, ve kterém má každý účastník svůj úsek. Poměr se mění <strong>tažením předělu mezi úseky</strong>; pod pruhem je hned vidět, kolik z částky komu připadá.</p>
<p>Vedle jsou <strong>předvolby</strong> (<code>50 : 50</code>, <code>60 : 40</code>, <code>100 : 0</code> a podobně), což jsou jen zkratky k témuž – klepnutím se předěl přesune tam, kam patří.</p>
<p>Nejčastější případy:</p>
<ul>
<li><strong>Rovným dílem</strong> – výchozí stav, nic se nenastavuje.</li>
<li><strong>Někdo platí všechno</strong> – předvolba <code>100 : 0</code>. Hodí se, když jeden nakoupí něco, co je jen jeho, ale platí to ze společných.</li>
<li><strong>Nerovný poměr</strong> – tažením předělu nebo předvolbou.</li>
<li><strong>Přesné částky</strong> – když se jeden nákup rozpadá na položky, které patří různým lidem.</li>
</ul>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Procenta se zadávají v celých číslech. Když je potřeba jemnější poměr, použije se dělení v <strong>podílech</strong> – např. <code>335 : 665</code> znamená totéž jako 33,5 % ku 66,5 %.</p>
</div>
</div>
<p>Aplikace hlídá, aby součet <strong>vždycky seděl do haléře</strong>. Když se 100 Kč dělí na tři, vyjde 34 + 33 + 33 – nikdy ne tři třiatřicítky, u kterých by koruna zmizela.</p>
</section>
<section id="zopakování-výdaje" class="level3">
<h3 class="anchored" data-anchor-id="zopakování-výdaje">Zopakování výdaje</h3>
<p>U už uloženého výdaje je tlačítko na <strong>zopakování</strong>. Otevře nový formulář předvyplněný stejnými údaji, takže opakovaný nákup je otázka dvou klepnutí.</p>
</section>
<section id="oprava-a-smazání" class="level3">
<h3 class="anchored" data-anchor-id="oprava-a-smazání">Oprava a smazání</h3>
<p>Klepnutím na výdaj v <code>Platbách</code> se otevře k úpravě, kde jde i smazat. Smazání není nevratné – záznam zůstává v historii a správce ho dokáže obnovit.</p>
</section>
</section>
<section id="dluh-a-vyrovnání" class="level2">
<h2 class="anchored" data-anchor-id="dluh-a-vyrovnání">Dluh a vyrovnání</h2>
<p>Záložka <code>Dluh</code> říká jedinou věc: <strong>kdo komu kolik dluží</strong>, po započtení všech výdajů a všech dosavadních vyrovnání.</p>
<p>Když si dluh mezi sebou skutečně srovnáte (převodem, hotově), zapíše se to tlačítkem <code>Vyrovnat</code>. Předvyplní se celá dlužná částka, ale dá se přepsat – <strong>částečné vyrovnání je v pořádku</strong>, zbytek dluhu zůstane viset dál.</p>
<p>Vyrovnání je samostatný záznam, ne výdaj: nezapočítá se do statistik útraty, jen posune dluh. Dá se později upravit nebo smazat stejně jako výdaj.</p>
</section>
<section id="statistiky" class="level2">
<h2 class="anchored" data-anchor-id="statistiky">Statistiky</h2>
<p>Záložka <code>Statistiky</code> je jenom na čtení – nic se v ní nezadává.</p>
<p>Nahoře jsou souhrnná čísla za celou knihu. Pod nimi <strong>měsíční graf</strong>: sloupce ukazují, kolik se který měsíc utratilo, rozdělené barvami podle toho, <strong>koho ten měsíc co stálo</strong> (tedy podle konečného podílu, ne podle toho, kdo platil). Přes sloupce vede <strong>kumulativní čára</strong> – celková útrata od začátku. Má vlastní měřítko, proto je vysvětlená v legendě pod grafem.</p>
<p>Níž jsou rozpady: kdo kolik zaplatil, kolik se utratilo za jednotlivé štítky a co bylo nejdražší.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Tip
</div>
</div>
<div class="callout-body-container callout-body">
<p>Barva patří vždy konkrétnímu člověku, ne pořadí v žebříčku. Ve všech grafech tedy tentýž odstín znamená tutéž osobu.</p>
</div>
</div>
<p>Úplně dole je tlačítko <strong><code>Stáhnout CSV</code></strong>, které vyexportuje všechny výdaje do tabulky – k otevření v Excelu nebo v tabulkovém procesoru.</p>
</section>
<section id="nastavení" class="level2">
<h2 class="anchored" data-anchor-id="nastavení">Nastavení</h2>
<p>Otevírá se odkazem <code>Nastavení</code> v hlavičce. Každý tu najde:</p>
<ul>
<li><strong>Změnu vlastního hesla.</strong> Vyžaduje zadání toho stávajícího.</li>
</ul>
<p>Správce knihy navíc:</p>
<ul>
<li><strong>Název knihy.</strong> Objeví se v hlavičce, na přihlašovací obrazovce i v názvu aplikace na ploše.</li>
<li><strong>Správu účastníků.</strong> Přidání nového, přejmenování, nastavení hesla, udělení a odebrání práv správce.</li>
</ul>
<section id="přidání-účastníka" class="level3">
<h3 class="anchored" data-anchor-id="přidání-účastníka">Přidání účastníka</h3>
<p><code>Nastavení</code> → <code>Přidat účastníka</code>. Zadá se jméno a heslo, které novému účastníkovi předáte jinou cestou (ne v aplikaci). Restart ani nic dalšího potřeba není, přihlásit se může hned.</p>
</section>
<section id="odebrání-účastníka-archivace" class="level3">
<h3 class="anchored" data-anchor-id="odebrání-účastníka-archivace">Odebrání účastníka: archivace</h3>
<p>Účastníka, který už má v knize nějaké záznamy, <strong>nejde smazat</strong> – smazáním by přestalo dávat smysl vyčíslení dluhu u starých výdajů. Místo toho se <strong>archivuje</strong>:</p>
<ul>
<li>nepřihlásí se,</li>
<li>nenabízí se u nových výdajů,</li>
<li>ale v historii i ve vyčíslení dluhu zůstává přesně tak, jak byl.</li>
</ul>
<p>Účastník, který ještě nemá žádný záznam, se smazat dá.</p>
<div class="callout callout-style-default callout-important callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Important
</div>
</div>
<div class="callout-body-container callout-body">
<p>Kniha musí mít vždycky <strong>aspoň jednoho správce</strong>. Poslední správce si proto nemůže odebrat práva ani se archivovat.</p>
</div>
</div>
</section>
</section>
<section id="co-s-daty" class="level2">
<h2 class="anchored" data-anchor-id="co-s-daty">Co s daty</h2>
<p>Data nejsou v žádné databázi, ale v obyčejných souborech verzovaných gitem. V praxi to pro vás znamená tři věci:</p>
<ul>
<li><strong>Nic se neztrácí.</strong> Každá změna je zapsaná i s tím, kdo ji udělal a kdy. Smazaný výdaj jde dohledat a vrátit.</li>
<li><strong>Zálohou je kopie repozitáře.</strong> Když by server odešel, kniha se obnoví.</li>
<li><strong>Aplikace není podmínkou.</strong> I kdyby Ledrich zítra přestal existovat, data zůstávají čitelná běžnými nástroji.</li>
</ul>
<p>Jediné, co se takhle nezálohuje, jsou <strong>hesla</strong> – ta jsou schválně uložená jinde. Po obnově ze zálohy se prostě nastaví znovu.</p>
</section>
</main> <!-- /main -->
<script id="quarto-html-after-body" type="application/javascript">
window.document.addEventListener("DOMContentLoaded", function (event) {
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {
placement: 'right',
icon: icon
};
anchorJS.add('.anchored');
const isCodeAnnotation = (el) => {
for (const clz of el.classList) {
if (clz.startsWith('code-annotation-')) {
return true;
}
}
return false;
}
const onCopySuccess = function(e) {
// button target
const button = e.trigger;
// don't keep focus
button.blur();
// flash "checked"
button.classList.add('code-copy-button-checked');
var currentTitle = button.getAttribute("title");
button.setAttribute("title", "Copied!");
let tooltip;
if (window.bootstrap) {
button.setAttribute("data-bs-toggle", "tooltip");
button.setAttribute("data-bs-placement", "left");
button.setAttribute("data-bs-title", "Copied!");
tooltip = new bootstrap.Tooltip(button,
{ trigger: "manual",
customClass: "code-copy-button-tooltip",
offset: [0, -8]});
tooltip.show();
}
setTimeout(function() {
if (tooltip) {
tooltip.hide();
button.removeAttribute("data-bs-title");
button.removeAttribute("data-bs-toggle");
button.removeAttribute("data-bs-placement");
}
button.setAttribute("title", currentTitle);
button.classList.remove('code-copy-button-checked');
}, 1000);
// clear code selection
e.clearSelection();
}
const getTextToCopy = function(trigger) {
const outerScaffold = trigger.parentElement.cloneNode(true);
const codeEl = outerScaffold.querySelector('code');
for (const childEl of codeEl.children) {
if (isCodeAnnotation(childEl)) {
childEl.remove();
}
}
return codeEl.innerText;
}
const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
text: getTextToCopy
});
clipboard.on('success', onCopySuccess);
if (window.document.getElementById('quarto-embedded-source-code-modal')) {
const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
text: getTextToCopy,
container: window.document.getElementById('quarto-embedded-source-code-modal')
});
clipboardModal.on('success', onCopySuccess);
}
var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
var mailtoRegex = new RegExp(/^mailto:/);
var filterRegex = new RegExp("^(?:http:|https:)\/\/pages\.spacilovi\.eu\/david-spacil\/help");
var isInternal = (href) => {
return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
}
// Inspect non-navigation links and adorn them if external
var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
for (var i=0; i<links.length; i++) {
const link = links[i];
if (!isInternal(link.href)) {
// undo the damage that might have been done by quarto-nav.js in the case of
// links that we want to consider external
if (link.dataset.originalHref !== undefined) {
link.href = link.dataset.originalHref;
}
// target, if specified
link.setAttribute("target", "_blank");
if (link.getAttribute("rel") === null) {
link.setAttribute("rel", "noopener");
}
// default icon
link.classList.add("external");
}
}
function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
const config = {
allowHTML: true,
maxWidth: 500,
delay: 100,
arrow: false,
appendTo: function(el) {
return el.parentElement;
},
interactive: true,
interactiveBorder: 10,
theme: 'quarto',
placement: 'bottom-start',
};
if (contentFn) {
config.content = contentFn;
}
if (onTriggerFn) {
config.onTrigger = onTriggerFn;
}
if (onUntriggerFn) {
config.onUntrigger = onUntriggerFn;
}
window.tippy(el, config);
}
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
for (var i=0; i<noterefs.length; i++) {
const ref = noterefs[i];
tippyHover(ref, function() {
// use id or data attribute instead here
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
try { href = new URL(href).hash; } catch {}
const id = href.replace(/^#\/?/, "");
const note = window.document.getElementById(id);
if (note) {
return note.innerHTML;
} else {
return "";
}
});
}
const xrefs = window.document.querySelectorAll('a.quarto-xref');
const processXRef = (id, note) => {
// Strip column container classes
const stripColumnClz = (el) => {
el.classList.remove("page-full", "page-columns");
if (el.children) {
for (const child of el.children) {
stripColumnClz(child);
}
}
}
stripColumnClz(note)
if (id === null || id.startsWith('sec-')) {
// Special case sections, only their first couple elements
const container = document.createElement("div");
if (note.children && note.children.length > 2) {
container.appendChild(note.children[0].cloneNode(true));
for (let i = 1; i < note.children.length; i++) {
const child = note.children[i];
if (child.tagName === "P" && child.innerText === "") {
continue;
} else {
container.appendChild(child.cloneNode(true));
break;
}
}
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(container);
}
return container.innerHTML
} else {
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(note);
}
return note.innerHTML;
}
} else {
// Remove any anchor links if they are present
const anchorLink = note.querySelector('a.anchorjs-link');
if (anchorLink) {
anchorLink.remove();
}
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(note);
}
if (note.classList.contains("callout")) {
return note.outerHTML;
} else {
return note.innerHTML;
}
}
}
for (var i=0; i<xrefs.length; i++) {
const xref = xrefs[i];
tippyHover(xref, undefined, function(instance) {
instance.disable();
let url = xref.getAttribute('href');
let hash = undefined;
if (url.startsWith('#')) {
hash = url;
} else {
try { hash = new URL(url).hash; } catch {}
}
if (hash) {
const id = hash.replace(/^#\/?/, "");
const note = window.document.getElementById(id);
if (note !== null) {
try {
const html = processXRef(id, note.cloneNode(true));
instance.setContent(html);
} finally {
instance.enable();
instance.show();
}
} else {
// See if we can fetch this
fetch(url.split('#')[0])
.then(res => res.text())
.then(html => {
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(html, "text/html");
const note = htmlDoc.getElementById(id);
if (note !== null) {
const html = processXRef(id, note);
instance.setContent(html);
}
}).finally(() => {
instance.enable();
instance.show();
});
}
} else {
// See if we can fetch a full url (with no hash to target)
// This is a special case and we should probably do some content thinning / targeting
fetch(url)
.then(res => res.text())
.then(html => {
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(html, "text/html");
const note = htmlDoc.querySelector('main.content');
if (note !== null) {
// This should only happen for chapter cross references
// (since there is no id in the URL)
// remove the first header
if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
note.children[0].remove();
}
const html = processXRef(null, note);
instance.setContent(html);
}
}).finally(() => {
instance.enable();
instance.show();
});
}
}, function(instance) {
});
}
let selectedAnnoteEl;
const selectorForAnnotation = ( cell, annotation) => {
let cellAttr = 'data-code-cell="' + cell + '"';
let lineAttr = 'data-code-annotation="' + annotation + '"';
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
return selector;
}
const selectCodeLines = (annoteEl) => {
const doc = window.document;
const targetCell = annoteEl.getAttribute("data-target-cell");
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
const lineIds = lines.map((line) => {
return targetCell + "-" + line;
})
let top = null;
let height = null;
let parent = null;
if (lineIds.length > 0) {
//compute the position of the single el (top and bottom and make a div)
const el = window.document.getElementById(lineIds[0]);
top = el.offsetTop;
height = el.offsetHeight;
parent = el.parentElement.parentElement;
if (lineIds.length > 1) {
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
height = bottom - top;
}
if (top !== null && height !== null && parent !== null) {
// cook up a div (if necessary) and position it
let div = window.document.getElementById("code-annotation-line-highlight");
if (div === null) {
div = window.document.createElement("div");
div.setAttribute("id", "code-annotation-line-highlight");
div.style.position = 'absolute';
parent.appendChild(div);
}
div.style.top = top - 2 + "px";
div.style.height = height + 4 + "px";
div.style.left = 0;
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
if (gutterDiv === null) {
gutterDiv = window.document.createElement("div");
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
gutterDiv.style.position = 'absolute';
const codeCell = window.document.getElementById(targetCell);
const gutter = codeCell.querySelector('.code-annotation-gutter');
gutter.appendChild(gutterDiv);
}
gutterDiv.style.top = top - 2 + "px";
gutterDiv.style.height = height + 4 + "px";
}
selectedAnnoteEl = annoteEl;
}
};
const unselectCodeLines = () => {
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
elementsIds.forEach((elId) => {
const div = window.document.getElementById(elId);
if (div) {
div.remove();
}
});
selectedAnnoteEl = undefined;
};
// Handle positioning of the toggle
window.addEventListener(
"resize",
throttle(() => {
elRect = undefined;
if (selectedAnnoteEl) {
selectCodeLines(selectedAnnoteEl);
}
}, 10)
);
function throttle(fn, ms) {
let throttle = false;
let timer;
return (...args) => {
if(!throttle) { // first call gets through
fn.apply(this, args);
throttle = true;
} else { // all the others get throttled
if(timer) clearTimeout(timer); // cancel #2
timer = setTimeout(() => {
fn.apply(this, args);
timer = throttle = false;
}, ms);
}
};
}
// Attach click handler to the DT
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
for (const annoteDlNode of annoteDls) {
annoteDlNode.addEventListener('click', (event) => {
const clickedEl = event.target;
if (clickedEl !== selectedAnnoteEl) {
unselectCodeLines();
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
if (activeEl) {
activeEl.classList.remove('code-annotation-active');
}
selectCodeLines(clickedEl);
clickedEl.classList.add('code-annotation-active');
} else {
// Unselect the line
unselectCodeLines();
clickedEl.classList.remove('code-annotation-active');
}
});
}
const findCites = (el) => {
const parentEl = el.parentElement;
if (parentEl) {
const cites = parentEl.dataset.cites;
if (cites) {
return {
el,
cites: cites.split(' ')
};
} else {
return findCites(el.parentElement)
}
} else {
return undefined;
}
};
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
for (var i=0; i<bibliorefs.length; i++) {
const ref = bibliorefs[i];
const citeInfo = findCites(ref);
if (citeInfo) {
tippyHover(citeInfo.el, function() {
var popup = window.document.createElement('div');
citeInfo.cites.forEach(function(cite) {
var citeDiv = window.document.createElement('div');
citeDiv.classList.add('hanging-indent');
citeDiv.classList.add('csl-entry');
var biblioDiv = window.document.getElementById('ref-' + cite);
if (biblioDiv) {
citeDiv.innerHTML = biblioDiv.innerHTML;
}
popup.appendChild(citeDiv);
});
return popup.innerHTML;
});
}
}
});
</script>
</div> <!-- /content -->
<footer class="footer"><div class="nav-footer"><div class="nav-footer-center"><div class="toc-actions d-sm-block d-md-none"><ul><li><a href="https://gitea.spacilovi.eu/david-spacil/help/issues/new" class="toc-action"><i class="bi bi-git"></i>Report an issue</a></li></ul></div></div></div></footer></body></html>
+88
View File
@@ -61,6 +61,94 @@
"Návod na používání Immich"
]
},
{
"objectID": "navody/ledrich.html",
"href": "navody/ledrich.html",
"title": "Návod na používání Ledriche",
"section": "",
"text": "Ledrich je aplikace na evidenci společných výdajů a dělení nákladů – tedy na situace, kdy se skládá víc lidí a nikomu se nechce vést papírové poznámky o tom, kdo co zaplatil a komu kolik dluží. Funguje podobně jako známé appky typu Splitwise nebo Tricount, ale běží na našem vlastním serveru, takže data o tom, za co utrácíme, nikam ven neodcházejí. Používá se hlavně z mobilu – aplikace je udělaná tak, aby se výdaj dal zadat jednou rukou cestou z obchodu.\nVede se v ní kniha: seznam účastníků, kteří se o výdaje dělí, a všechny jejich platby.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#přihlášení",
"href": "navody/ledrich.html#přihlášení",
"title": "Návod na používání Ledriche",
"section": "Přihlášení",
"text": "Přihlášení\nRegistrace není možná, účty zakládá správce knihy. Když se má někdo přidat, správce ho přidá v Nastavení a předá mu heslo.\nNa přihlašovací obrazovce se vybere jméno ze seznamu a zadá heslo. Po přihlášení zůstáváte přihlášení dlouhodobě, takže se na mobilu heslo zadává jen výjimečně.\n\n\n\n\n\n\nTip\n\n\n\nAplikaci si na mobilu můžete přidat na plochu (v prohlížeči Přidat na plochu / Add to Home Screen). Pak se otevírá jako běžná appka, na celou obrazovku a bez adresního řádku.\n\n\nPokud po zadání hesla obrazovka „probliknutím“ spadne zpátky na přihlášení, aplikace vám sama napíše proč – nejčastěji je to tím, že se k ní jde přes nezabezpečené spojení.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#orientace-v-prostředí",
"href": "navody/ledrich.html#orientace-v-prostředí",
"title": "Návod na používání Ledriche",
"section": "Orientace v prostředí",
"text": "Orientace v prostředí\nDole jsou tři záložky a nad nimi oranžové kolečko s plusem.\n\nPlatby – seznam všech výdajů, od nejnovějšího. Klepnutím na výdaj se otevře k úpravě.\nDluh – kdo komu kolik dluží a tlačítko na vyrovnání.\nStatistiky – souhrnná čísla, graf v čase a rozpady.\nOranžové tlačítko + – přidání výdaje. Je záměrně mimo záložky a nad nimi, protože je to jediná činnost, kvůli které se aplikace otevírá venku, a musí být na dosah palce.\n\nOranžová barva patří v celé aplikaci jen tomuhle tlačítku, takže je vždycky jasné, kam sáhnout.\nNahoře je název knihy a vedle něj Nastavení a Odhlásit.\n\n\n\n\n\n\nNote\n\n\n\nKdyž v hlavičce občas problikne informace o čekajících změnách, znamená to, že byl výpadek spojení se serverem. Nic se neztratilo – zadané výdaje jsou uložené a odešlou se samy, jakmile se spojení vrátí.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#přidání-výdaje",
"href": "navody/ledrich.html#přidání-výdaje",
"title": "Návod na používání Ledriche",
"section": "Přidání výdaje",
"text": "Přidání výdaje\nKlepnutím na oranžové + se otevře formulář. Vyplňuje se:\n\nČástka – hlavní pole, samo se zaostří. Zadává se v korunách, haléře se dají zapsat za desetinnou čárkou.\nZa co – krátký popis, např. nákup Lidl.\nKdo platil – ten, kdo peníze skutečně vytáhl z kapsy. Není to totéž jako to, koho výdaj stál (viz dělení níž).\nDatum – předvyplněné na dnešek.\nJak se to dělí – viz další sekce.\nŠtítky – nepovinné, slouží k roztřídění výdajů. Nabízejí se dřív použité, nový se prostě napíše.\nPoznámka – nepovinná, na cokoli, co se nevejde do popisu.\n\nUloží se tlačítkem Přidat výdaj.\n\nJak se výdaj dělí\nTohle je jádro celé aplikace. Pod formulářem je dělicí pruh – vodorovný proužek, ve kterém má každý účastník svůj úsek. Poměr se mění tažením předělu mezi úseky; pod pruhem je hned vidět, kolik z částky komu připadá.\nVedle jsou předvolby (50 : 50, 60 : 40, 100 : 0 a podobně), což jsou jen zkratky k témuž – klepnutím se předěl přesune tam, kam patří.\nNejčastější případy:\n\nRovným dílem – výchozí stav, nic se nenastavuje.\nNěkdo platí všechno – předvolba 100 : 0. Hodí se, když jeden nakoupí něco, co je jen jeho, ale platí to ze společných.\nNerovný poměr – tažením předělu nebo předvolbou.\nPřesné částky – když se jeden nákup rozpadá na položky, které patří různým lidem.\n\n\n\n\n\n\n\nNote\n\n\n\nProcenta se zadávají v celých číslech. Když je potřeba jemnější poměr, použije se dělení v podílech – např. 335 : 665 znamená totéž jako 33,5 % ku 66,5 %.\n\n\nAplikace hlídá, aby součet vždycky seděl do haléře. Když se 100 Kč dělí na tři, vyjde 34 + 33 + 33 – nikdy ne tři třiatřicítky, u kterých by koruna zmizela.\n\n\nZopakování výdaje\nU už uloženého výdaje je tlačítko na zopakování. Otevře nový formulář předvyplněný stejnými údaji, takže opakovaný nákup je otázka dvou klepnutí.\n\n\nOprava a smazání\nKlepnutím na výdaj v Platbách se otevře k úpravě, kde jde i smazat. Smazání není nevratné – záznam zůstává v historii a správce ho dokáže obnovit.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#dluh-a-vyrovnání",
"href": "navody/ledrich.html#dluh-a-vyrovnání",
"title": "Návod na používání Ledriche",
"section": "Dluh a vyrovnání",
"text": "Dluh a vyrovnání\nZáložka Dluh říká jedinou věc: kdo komu kolik dluží, po započtení všech výdajů a všech dosavadních vyrovnání.\nKdyž si dluh mezi sebou skutečně srovnáte (převodem, hotově), zapíše se to tlačítkem Vyrovnat. Předvyplní se celá dlužná částka, ale dá se přepsat – částečné vyrovnání je v pořádku, zbytek dluhu zůstane viset dál.\nVyrovnání je samostatný záznam, ne výdaj: nezapočítá se do statistik útraty, jen posune dluh. Dá se později upravit nebo smazat stejně jako výdaj.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#statistiky",
"href": "navody/ledrich.html#statistiky",
"title": "Návod na používání Ledriche",
"section": "Statistiky",
"text": "Statistiky\nZáložka Statistiky je jenom na čtení – nic se v ní nezadává.\nNahoře jsou souhrnná čísla za celou knihu. Pod nimi měsíční graf: sloupce ukazují, kolik se který měsíc utratilo, rozdělené barvami podle toho, koho ten měsíc co stálo (tedy podle konečného podílu, ne podle toho, kdo platil). Přes sloupce vede kumulativní čára – celková útrata od začátku. Má vlastní měřítko, proto je vysvětlená v legendě pod grafem.\nNíž jsou rozpady: kdo kolik zaplatil, kolik se utratilo za jednotlivé štítky a co bylo nejdražší.\n\n\n\n\n\n\nTip\n\n\n\nBarva patří vždy konkrétnímu člověku, ne pořadí v žebříčku. Ve všech grafech tedy tentýž odstín znamená tutéž osobu.\n\n\nÚplně dole je tlačítko Stáhnout CSV, které vyexportuje všechny výdaje do tabulky – k otevření v Excelu nebo v tabulkovém procesoru.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#nastavení",
"href": "navody/ledrich.html#nastavení",
"title": "Návod na používání Ledriche",
"section": "Nastavení",
"text": "Nastavení\nOtevírá se odkazem Nastavení v hlavičce. Každý tu najde:\n\nZměnu vlastního hesla. Vyžaduje zadání toho stávajícího.\n\nSprávce knihy navíc:\n\nNázev knihy. Objeví se v hlavičce, na přihlašovací obrazovce i v názvu aplikace na ploše.\nSprávu účastníků. Přidání nového, přejmenování, nastavení hesla, udělení a odebrání práv správce.\n\n\nPřidání účastníka\nNastavení → Přidat účastníka. Zadá se jméno a heslo, které novému účastníkovi předáte jinou cestou (ne v aplikaci). Restart ani nic dalšího potřeba není, přihlásit se může hned.\n\n\nOdebrání účastníka: archivace\nÚčastníka, který už má v knize nějaké záznamy, nejde smazat – smazáním by přestalo dávat smysl vyčíslení dluhu u starých výdajů. Místo toho se archivuje:\n\nnepřihlásí se,\nnenabízí se u nových výdajů,\nale v historii i ve vyčíslení dluhu zůstává přesně tak, jak byl.\n\nÚčastník, který ještě nemá žádný záznam, se smazat dá.\n\n\n\n\n\n\nImportant\n\n\n\nKniha musí mít vždycky aspoň jednoho správce. Poslední správce si proto nemůže odebrat práva ani se archivovat.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "navody/ledrich.html#co-s-daty",
"href": "navody/ledrich.html#co-s-daty",
"title": "Návod na používání Ledriche",
"section": "Co s daty",
"text": "Co s daty\nData nejsou v žádné databázi, ale v obyčejných souborech verzovaných gitem. V praxi to pro vás znamená tři věci:\n\nNic se neztrácí. Každá změna je zapsaná i s tím, kdo ji udělal a kdy. Smazaný výdaj jde dohledat a vrátit.\nZálohou je kopie repozitáře. Když by server odešel, kniha se obnoví.\nAplikace není podmínkou. I kdyby Ledrich zítra přestal existovat, data zůstávají čitelná běžnými nástroji.\n\nJediné, co se takhle nezálohuje, jsou hesla – ta jsou schválně uložená jinde. Po obnově ze zálohy se prostě nastaví znovu.",
"crumbs": [
"Návody",
"Návod na používání Ledriche"
]
},
{
"objectID": "index.html",
"href": "index.html",