diff --git a/appinfo.json b/appinfo.json new file mode 100644 index 0000000..9bc5c51 --- /dev/null +++ b/appinfo.json @@ -0,0 +1,10 @@ +{ + "name": "Projekcija", + "description": "Aplikacija za projekcijo besedil pesmi na zaslon.", + "version": "0.6.91", + "authors": [ + "Uroš Urbanija (izvorna zasnova)", + "Valentin Korenjak (nadgradnje in vzdrževanje)" + ], + "license": "GPLv3" +} diff --git a/web/server.py b/web/server.py index f1cb92d..cce6bc3 100644 --- a/web/server.py +++ b/web/server.py @@ -27,6 +27,7 @@ than being generated inside Python code. import threading import os +import json from flask import Flask, render_template, request, jsonify @@ -160,6 +161,18 @@ def toggle_split(): return jsonify({'status': 'ok'}) +@app.route('/api/app_info', methods=['GET']) +def get_app_info(): + """Vrne informacije o aplikaciji iz appinfo.json""" + try: + # appinfo.json je v korenskem imeniku projekta + with open('appinfo.json', 'r', encoding='utf-8') as f: + info = json.load(f) + return jsonify(info) + except Exception as e: + return jsonify({'error': str(e)}), 500 + + @app.route('/api/search_songs', methods=['POST']) def search_songs(): """Iskanje besedil po naslovu""" diff --git a/web/static/script.js b/web/static/script.js index a774af0..59a5092 100644 --- a/web/static/script.js +++ b/web/static/script.js @@ -10,6 +10,9 @@ const darkBtn = document.getElementById('dark-btn'); const splitBtn = document.getElementById('split-btn'); const pageInfo = document.getElementById('page-info'); const clearBtn = document.getElementById('clear-btn'); +const aboutBtn = document.getElementById('about-btn'); +const aboutModal = document.getElementById('about-modal'); +const aboutCloseBtn = document.getElementById('about-close-btn'); const keypadButtons = document.querySelectorAll('.btn-key'); const keypadWrapper = document.getElementById('keypad-wrapper'); const toggleKeypadBtn = document.getElementById('toggle-keypad-btn'); @@ -345,6 +348,36 @@ async function saveSongEdit() { } } +// Odpri About dialog +async function openAbout() { + try { + const response = await fetch('/api/app_info'); + const data = await response.json(); + + if (data.error) { + alert('Napaka pri pridobivanju informacij o programu.'); + return; + } + + document.getElementById('about-name').textContent = data.name; + document.getElementById('about-version').textContent = 'Verzija ' + data.version; + document.getElementById('about-description').textContent = data.description; + + const authorsList = document.getElementById('about-authors'); + authorsList.innerHTML = ''; + data.authors.forEach(author => { + const li = document.createElement('li'); + li.textContent = author; + authorsList.appendChild(li); + }); + + aboutModal.classList.add('show'); + menuDropdown.classList.remove('show'); + } catch (error) { + console.error('Napaka pri pridobivanju informacij o programu:', error); + } +} + // skrij/pokaži tipkovnico function toggleKeypad() { if (!keypadWrapper || !toggleKeypadBtn) return; @@ -419,6 +452,20 @@ if (toggleKeypadBtn) { }); } +// O programu +if (aboutBtn) { + aboutBtn.addEventListener('click', () => { + vibrate(); + openAbout(); + }); +} + +if (aboutCloseBtn) { + aboutCloseBtn.addEventListener('click', () => { + aboutModal.classList.remove('show'); + }); +} + // Uredi besedilo if (editSongBtn) { editSongBtn.addEventListener('click', () => { @@ -489,6 +536,10 @@ document.addEventListener('click', (e) => { if (menuDropdown && !menuDropdown.contains(e.target) && e.target !== menuToggle) { menuDropdown.classList.remove('show'); } + // Zapri About modal ob kliku izven vsebine + if (e.target === aboutModal) { + aboutModal.classList.remove('show'); + } }); // Iskanje dogodki diff --git a/web/static/styles.css b/web/static/styles.css index 8813931..0fe155a 100644 --- a/web/static/styles.css +++ b/web/static/styles.css @@ -429,6 +429,12 @@ body { height: 100%; background-color: rgba(0,0,0,0.8); overflow-y: auto; + align-items: center; + justify-content: center; +} + +.modal.show { + display: flex !important; } .modal-content { @@ -474,6 +480,59 @@ textarea.form-control { margin-top: 20px; } +/* About Modal Styles */ +.about-content { + text-align: center; + padding: 30px; +} + +.about-header { + margin-bottom: 25px; +} + +.about-logo { + width: 96px; + height: 96px; + margin-bottom: 15px; +} + +.about-version { + color: var(--text-muted); + font-size: 0.9rem; + margin-top: 5px; +} + +.about-description { + font-size: 1.1rem; + margin-bottom: 25px; + line-height: 1.5; +} + +.about-authors-section { + text-align: left; + background: rgba(255, 255, 255, 0.05); + padding: 15px; + border-radius: 8px; + margin-bottom: 20px; +} + +.about-authors-section h3 { + margin-top: 0; + font-size: 1rem; + color: #1f8a46; +} + +.about-authors-list { + list-style: none; + padding: 0; + margin: 10px 0 0 0; +} + +.about-authors-list li { + margin-bottom: 5px; + font-size: 0.95rem; +} + .btn-primary { background-color: #1f8a46; color: white; diff --git a/web/templates/index.html b/web/templates/index.html index 0edac2c..06f13b6 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -28,6 +28,7 @@ + @@ -79,6 +80,27 @@ + + +