Compare commits
2 Commits
main
..
db91775a5d
| Author | SHA1 | Date | |
|---|---|---|---|
| db91775a5d | |||
| 6b15afb9da |
+1
-5
@@ -1,5 +1 @@
|
||||
*:Zone.Identifier
|
||||
*Zone.Identifier
|
||||
*.old
|
||||
/api/*
|
||||
.htaccess
|
||||
*:Zone.Identifier
|
||||
@@ -0,0 +1,77 @@
|
||||
# Abilita il rewrite engine
|
||||
RewriteEngine On
|
||||
|
||||
# Imposta la directory base (modifica se necessario)
|
||||
# Se l'app è in una sottocartella, usa: RewriteBase /nome_cartella/
|
||||
RewriteBase /newapp.rpigroup.it/
|
||||
|
||||
# Reindirizza richieste HTTP a HTTPS (opzionale, decommentare se necessario)
|
||||
# RewriteCond %{HTTPS} off
|
||||
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# Non reindirizzare file e cartelle esistenti
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# Escludi file statici dal rewriting
|
||||
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|jpeg|png|gif|svg|ico|xml|json|woff|woff2|ttf|eot)$ [NC]
|
||||
|
||||
# Reindirizza tutto a index.php mantenendo il path
|
||||
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
|
||||
|
||||
# Impedisci l'accesso diretto a file sensibili
|
||||
<FilesMatch "^(config|\.htaccess|\.env)">
|
||||
Order Allow,Deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
|
||||
# Gestione MIME types
|
||||
<IfModule mod_mime.c>
|
||||
AddType application/javascript js
|
||||
AddType text/css css
|
||||
AddType image/svg+xml svg
|
||||
AddType application/vnd.ms-fontobject eot
|
||||
AddType font/ttf ttf
|
||||
AddType font/otf otf
|
||||
AddType font/woff woff
|
||||
AddType font/woff2 woff2
|
||||
</IfModule>
|
||||
|
||||
# Abilita compressione GZIP (opzionale)
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
|
||||
</IfModule>
|
||||
|
||||
# Cache control (opzionale - commentato perché hai lo script no-cache)
|
||||
# <IfModule mod_expires.c>
|
||||
# ExpiresActive On
|
||||
# ExpiresByType image/jpg "access plus 1 month"
|
||||
# ExpiresByType image/jpeg "access plus 1 month"
|
||||
# ExpiresByType image/gif "access plus 1 month"
|
||||
# ExpiresByType image/png "access plus 1 month"
|
||||
# ExpiresByType image/svg+xml "access plus 1 month"
|
||||
# ExpiresByType text/css "access plus 1 week"
|
||||
# ExpiresByType application/javascript "access plus 1 week"
|
||||
# </IfModule>
|
||||
|
||||
# Header no-cache per sviluppo (rimuovi in produzione se usi la cache)
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(html|php)$">
|
||||
Header set Cache-Control "no-cache, no-store, must-revalidate"
|
||||
Header set Pragma "no-cache"
|
||||
Header set Expires "0"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Sicurezza aggiuntiva
|
||||
<IfModule mod_headers.c>
|
||||
Header set X-Content-Type-Options "nosniff"
|
||||
Header set X-Frame-Options "SAMEORIGIN"
|
||||
Header set X-XSS-Protection "1; mode=block"
|
||||
</IfModule>
|
||||
|
||||
# Disabilita directory listing
|
||||
Options -Indexes
|
||||
|
||||
# Abilita follow symlinks (necessario per RewriteRule)
|
||||
Options +FollowSymLinks
|
||||
Binary file not shown.
@@ -35,9 +35,6 @@ if ($is_ajax) {
|
||||
include './pages/page/404.php';
|
||||
}
|
||||
break;
|
||||
case 'podcast':
|
||||
include './pages/page/podcast.php';
|
||||
break;
|
||||
case 'page':
|
||||
switch ($param) {
|
||||
case 'about':
|
||||
@@ -49,6 +46,9 @@ if ($is_ajax) {
|
||||
case 'copyright':
|
||||
include './pages/page/copyright.php';
|
||||
break;
|
||||
case 'addradio':
|
||||
include './pages/page/addradio.php';
|
||||
break;
|
||||
case 'termini-condizioni':
|
||||
include './pages/page/terminicondizioni.php';
|
||||
break;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,8 +5,8 @@ header('Content-Type: text/html; charset=UTF-8');
|
||||
// File: config/getPage.inc.php
|
||||
|
||||
// Whitelist delle pagine valide
|
||||
$validPages = ['home', 'radio', 'tv', 'play', 'playtv', 'page', 'podcast'];
|
||||
$validSubPages = ['about', 'contact', 'copyright', 'termini-condizioni', 'policy-privacy', 'changelog'];
|
||||
$validPages = ['home', 'radio', 'tv', 'play', 'playtv', 'page'];
|
||||
$validSubPages = ['about', 'contact', 'copyright', 'addradio', 'termini-condizioni', 'policy-privacy', 'changelog'];
|
||||
|
||||
// Rileva se l'utente sta usando un dispositivo mobile
|
||||
function isMobile() {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+18
-89
@@ -3,76 +3,8 @@
|
||||
======================================== */
|
||||
|
||||
|
||||
/* ========================================
|
||||
LOADING OVERLAY
|
||||
======================================== */
|
||||
|
||||
/* Overlay di caricamento a schermo intero */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(16, 25, 75, 0.95);
|
||||
backdrop-filter: blur(8px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
||||
}
|
||||
|
||||
/* Quando l'overlay è attivo */
|
||||
.loading-overlay.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Contenuto dell'overlay */
|
||||
.loading-content {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Spinner grande per il loading overlay */
|
||||
.spinner-large {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border: 5px solid rgba(255, 255, 255, 0.2);
|
||||
border-top-color: #f7b835;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
|
||||
/* Testo di caricamento */
|
||||
.loading-text {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
color: white;
|
||||
margin: 0;
|
||||
animation: pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Animazione pulse per il testo */
|
||||
@keyframes pulse {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Transizione per i link di navigazione */
|
||||
/* .navLink,
|
||||
.navLink,
|
||||
.nav-link,
|
||||
.station-link,
|
||||
.linkBox {
|
||||
@@ -81,7 +13,7 @@
|
||||
}
|
||||
|
||||
/* Effetto hover sui link */
|
||||
/* .navLink:hover,
|
||||
.navLink:hover,
|
||||
.nav-link:hover,
|
||||
.station-link:hover,
|
||||
.linkBox:hover {
|
||||
@@ -93,13 +25,10 @@
|
||||
|
||||
|
||||
@keyframes pulseActive {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
transform: translateX(-50%) scale(1.2);
|
||||
@@ -107,7 +36,7 @@
|
||||
}
|
||||
|
||||
/* Effetto click/tap */
|
||||
/* .navLink:active,
|
||||
.navLink:active,
|
||||
.nav-link:active,
|
||||
.station-link:active,
|
||||
.linkBox:active {
|
||||
@@ -116,7 +45,7 @@
|
||||
}
|
||||
|
||||
/* Transizione per le card delle stazioni */
|
||||
/*.station-card {
|
||||
.station-card {
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -126,7 +55,7 @@
|
||||
}
|
||||
|
||||
/* Transizione per i clickBox della home */
|
||||
/* .clickBox {
|
||||
.clickBox {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -171,7 +100,7 @@
|
||||
}
|
||||
|
||||
/* Transizione per elementi che appaiono */
|
||||
/*.content-page,
|
||||
.content-page,
|
||||
.station-list,
|
||||
.player-container {
|
||||
animation: fadeInContent 0.5s ease-out;
|
||||
@@ -187,7 +116,7 @@
|
||||
}
|
||||
|
||||
/* Transizione per le immagini */
|
||||
/* .station-logo,
|
||||
.station-logo,
|
||||
.station-logo-large {
|
||||
transition: transform 0.3s ease, filter 0.3s ease;
|
||||
}
|
||||
@@ -199,7 +128,7 @@
|
||||
}
|
||||
|
||||
/* Transizione per i pulsanti */
|
||||
/* button,
|
||||
button,
|
||||
.submit-btn,
|
||||
.play-pause-btn {
|
||||
transition: all 0.3s ease;
|
||||
@@ -219,7 +148,7 @@ button:active,
|
||||
}
|
||||
|
||||
/* Transizione smooth per tutti gli elementi interattivi */
|
||||
/* a, button, input, textarea, select {
|
||||
a, button, input, textarea, select {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@@ -227,7 +156,7 @@ button:active,
|
||||
/* Non ci sono più after pseudo-elementi per le underline */
|
||||
|
||||
/* Transizione per il back-link */
|
||||
/* .back-link a {
|
||||
.back-link a {
|
||||
transition: all 0.3s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -238,7 +167,7 @@ button:active,
|
||||
}
|
||||
|
||||
/* Animazione per le liste */
|
||||
/* .stations-container {
|
||||
.stations-container {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
@@ -265,7 +194,7 @@ button:active,
|
||||
}
|
||||
|
||||
/* Transizione per i form */
|
||||
/* .form-group input,
|
||||
.form-group input,
|
||||
.form-group textarea,
|
||||
.form-group select {
|
||||
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||
@@ -279,7 +208,7 @@ button:active,
|
||||
}
|
||||
|
||||
/* Animazione per i messaggi di risposta */
|
||||
/* .form-response {
|
||||
.form-response {
|
||||
animation: slideInDown 0.4s ease-out;
|
||||
}
|
||||
|
||||
@@ -295,7 +224,7 @@ button:active,
|
||||
}
|
||||
|
||||
/* Transizione per video e iframe */
|
||||
/* video,
|
||||
video,
|
||||
iframe {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
@@ -306,17 +235,17 @@ iframe:hover {
|
||||
}
|
||||
|
||||
/* Performance optimization */
|
||||
/** {
|
||||
* {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* Smooth scrolling */
|
||||
/* html {
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Riduzione movimento per chi ha impostato preferenze di accessibilità */
|
||||
/*@media (prefers-reduced-motion: reduce) {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
|
||||
Binary file not shown.
Vendored
+457
-1403
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+26
-47
@@ -112,7 +112,7 @@ div.dbox_mobile {
|
||||
|
||||
div.dbox_mobile {
|
||||
width: 90%;
|
||||
max-width: 750px;
|
||||
max-width: 450px;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
max-height: 475px;
|
||||
@@ -163,7 +163,7 @@ div.dfooter {
|
||||
|
||||
.appBody {
|
||||
background-color: #10194b;
|
||||
max-width: 750px;
|
||||
max-width: 450px;
|
||||
min-width: 330px;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
@@ -210,8 +210,6 @@ main {
|
||||
background-color: white;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.titlePage {
|
||||
@@ -252,14 +250,16 @@ main {
|
||||
|
||||
.changelogTitle {
|
||||
font-weight: 600;
|
||||
padding: 0 13px;
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
|
||||
.changelogList,
|
||||
.tec,
|
||||
.stationList {
|
||||
margin: 0 0 10px;
|
||||
text-align: left;
|
||||
padding: 0 13px;
|
||||
margin: 0 0 7px;
|
||||
text-align: justify;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
@@ -289,12 +289,12 @@ main {
|
||||
margin: 0;
|
||||
} */
|
||||
|
||||
.stationCard.isthematic {
|
||||
.stationCard.isthematic{
|
||||
text-align: right;
|
||||
margin-top: -24px;
|
||||
}
|
||||
|
||||
.stationCard.isthematic:before {
|
||||
.stationCard.isthematic:before{
|
||||
content: "Tematica";
|
||||
position: relative;
|
||||
background: #f7b835;
|
||||
@@ -308,38 +308,42 @@ main {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
iframe.contentplayer {
|
||||
height: calc(100vh - 393px);
|
||||
iframe.contentplayer{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
height: calc(100vh - 312px);
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
max-width: 450px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.footer_player {
|
||||
.footer_player{
|
||||
background: #f7b835;
|
||||
color: #2a377d;
|
||||
position: fixed;
|
||||
z-index: 90;
|
||||
bottom: 70px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
max-width: 450px;
|
||||
height: 100px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
padding: 20px;
|
||||
border-top: 1px solid #eee;
|
||||
flex: 1;
|
||||
align-content: end;
|
||||
}
|
||||
|
||||
.footer_player>.row>.col-2>img {
|
||||
.footer_player > .row > .col-2 > img{
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
button#playPauseBtn,
|
||||
button#formatToggleBtn {
|
||||
button#playPauseBtn{
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.footer,
|
||||
.header {
|
||||
z-index: 10000;
|
||||
.footer{
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.footer>.menu-section {
|
||||
@@ -394,28 +398,3 @@ button#formatToggleBtn {
|
||||
}
|
||||
|
||||
|
||||
/* Forza orientamento portrait - nasconde contenuto in landscape */
|
||||
@media screen and (orientation: landscape) and (max-height: 450px) {
|
||||
body.appBody::after {
|
||||
content: "Ruota il dispositivo in verticale";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #2a377e;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
z-index: 9999;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
body.appBody>* {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
+26
-111
@@ -2,95 +2,10 @@
|
||||
|
||||
<changelog>
|
||||
|
||||
<version>
|
||||
<number>2.5.1 (a)</number>
|
||||
<logs>
|
||||
<log>Migliorata l'usabilità e UX dell'applicazione, inserendo ad ogni pagina il pulsante "Back" (già presente in: player radio, tv e podcast)</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.5.0</number>
|
||||
<logs>
|
||||
<log>Aggiunta la pagina per la visualizzazione dei podcast.</log>
|
||||
<log>Rimossa la pagina per l'aggiunta delle nuove emittenti radiofoniche e televisive.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.4.2</number>
|
||||
<logs>
|
||||
<log>Aggiornata la grandezza della finestra dell'applicazione da desktop.</log>
|
||||
<log>Inserito il link della repository su ASV Git all'interno della pagina del changelog.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.4.1</number>
|
||||
<logs>
|
||||
<log>Aggiornata la pagiana del player audio, per renderla più coerente con le altre pagine dell'applicazione.</log>
|
||||
<log>Aggiunta la visualizzazione dell'artista e del brano in riproduzione.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.4.0</number>
|
||||
<logs>
|
||||
<log>Implementato il player video dedicato per la riproduzione dei canali visivi.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.3.0</number>
|
||||
<logs>
|
||||
<log>Ottimizzata la risoluzione dell'applicazione su dispositivi larghi (tablet, iPad e computer).</log>
|
||||
<log>Implementato lo switch tra il player audio in HLS e il player audio in MP3/AAC.</log>
|
||||
<log>Rimosso l'avviso per i dispositivi iOS.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.2.0</number>
|
||||
<logs>
|
||||
<log>E' stato reintrodotto la schermata di caricamento ad ogni selezione di ogni pagina dell'applicazione.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.1.4</number>
|
||||
<logs>
|
||||
<log>Corretto la visione verticale sui dispositivi mobili.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.1.3</number>
|
||||
<logs>
|
||||
<log>Implementato il nuovo player audio per la riproduzione dei flussi audio in HLS per il bitrate adattivo.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.1.2</number>
|
||||
<logs>
|
||||
<log>Implementazione del sistema di qualità adattiva (ABR) per il player audio.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
<version>
|
||||
<number>2.1.1</number>
|
||||
<logs>
|
||||
<log>Corretti alcuni bug che impedivano l'accesso al player dal link esterno.</log>
|
||||
<log>Corretti alcuni bug che impedivano l'accesso al player dal link esterno</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -98,8 +13,8 @@
|
||||
<version>
|
||||
<number>2.1.0</number>
|
||||
<logs>
|
||||
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi nella navigazione in app.</log>
|
||||
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi di riproduzione audio al player.</log>
|
||||
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi nella navigazione in app</log>
|
||||
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi di riproduzione audio al player</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -115,8 +30,8 @@
|
||||
<version>
|
||||
<number>2.0.3</number>
|
||||
<logs>
|
||||
<log>Corretta la visualizzazione dei contenuti forniti dalle emittenti all'interno del player.</log>
|
||||
<log>Corretta la visualizzazione del player audio.</log>
|
||||
<log>Corretta la visualizzazione dei contenuti forniti dalle emittenti all'interno del player</log>
|
||||
<log>Corretta la visualizzazione del player audio</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -124,7 +39,7 @@
|
||||
<version>
|
||||
<number>2.0.2</number>
|
||||
<logs>
|
||||
<log>Inserita la pagina statica per le emittenti tematiche.</log>
|
||||
<log>Inserita la pagina statica per le emittenti tematiche</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -132,7 +47,7 @@
|
||||
<version>
|
||||
<number>2.0.1</number>
|
||||
<logs>
|
||||
<log>Aggiunta la Visual Radio dell'emittente "Radio Città 105".</log>
|
||||
<log>Aggiunta la Visual Radio dell'emittente "Radio Città 105</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -140,7 +55,7 @@
|
||||
<version>
|
||||
<number>2.0.0</number>
|
||||
<logs>
|
||||
<log>Nuova UI/UX: RPIGroup aggiorna la veste grafica della sua applicazione, rendendola più "fumettosa" e "giocattolosa". Un'estetica completamente diversa da tutte le altre varie app radiofoniche.</log>
|
||||
<log>Nuova UI/UX: RPIGroup aggiorna la veste grafica della sua applicazione, rendendola più "fumettosa" e "giocattolosa". Un'estetica completamente diversa da tutte le altre varie app radiofoniche</log>
|
||||
<log>Nuova Engine: Nuovo motore e struttura dell'applicazione. Lato backend è cambiato completamente rispetto alla versione 1.</log>
|
||||
<log>Nuovo Player Audio/Video: Player più semplice, ma conserva le caratteristiche della precedente versione.</log>
|
||||
<log>Termini e Condizioni: inserimento per obblighi di legge dei corrispettivi "Termini e Condizioni"</log>
|
||||
@@ -161,7 +76,7 @@
|
||||
<version>
|
||||
<number>1.2.0 Stable</number>
|
||||
<logs>
|
||||
<log>Implementato il "Media Sessions" che permette di visualizzare la radio in riproduzione nel centro notifiche su iOS e Android.</log>
|
||||
<log>Implementato il "Media Sessions" che permette di visualizzare la radio in riproduzione nel centro notifiche su iOS e Android</log>
|
||||
<log>Preparazione dell'ottimizzazione del software in occasione della terza versione dell'app.</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
@@ -179,9 +94,9 @@
|
||||
<version>
|
||||
<number>1.1.0 Stable</number>
|
||||
<logs>
|
||||
<log>Aggiunta la nuova stazione radio tematica "RDL Revival 70-80-90".</log>
|
||||
<log>Migliorata la visualizzazione del selettore radio della pagina home.</log>
|
||||
<log>Implementato nel player la visualizzazione della pagina statica per le radio tematiche.</log>
|
||||
<log>Aggiunta la nuova stazione radio tematica "RDL Revival 70-80-90"</log>
|
||||
<log>Migliorata la visualizzazione del selettore radio della pagina home</log>
|
||||
<log>Implementato nel player la visualizzazione della pagina statica per le radio tematiche</log>
|
||||
<log>Correzione e bugfix di problematiche varie causate dall'ultima versione "Beta".</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -189,10 +104,10 @@
|
||||
<version>
|
||||
<number>1.0.0 Stable</number>
|
||||
<logs>
|
||||
<log>Passaggio alla versione "Stable" dell'applicazione.</log>
|
||||
<log>Verifica di ulteriori correzioni dal passaggio della versione stabile.</log>
|
||||
<log>Leggerimento dell'applicazione a livello backend.</log>
|
||||
<log>Ulteriori analisi di stabilità dal momento del passaggio alla versione stabile.</log>
|
||||
<log>Passaggio alla versione "Stable" dell'applicazione</log>
|
||||
<log>Verifica di ulteriori correzioni dal passaggio della versione stabile</log>
|
||||
<log>Leggerimento dell'applicazione a livello backend</log>
|
||||
<log>Ulteriori analisi di stabilità dal momento del passaggio alla versione stabile</log>
|
||||
<log>Correzione e bugfix di problematiche varie causate dall'ultima versione "Beta".</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -229,7 +144,7 @@
|
||||
<version>
|
||||
<number>0.23.1 Beta</number>
|
||||
<logs>
|
||||
<log>Rimozione del logo al caricamento di ogni singola pagina (tranne all'avvio dell'app).</log>
|
||||
<log>Rimozione del logo al caricamento di ogni singola pagina (tranne all'avvio dell'app)</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -237,8 +152,8 @@
|
||||
<version>
|
||||
<number>0.23.0 Beta</number>
|
||||
<logs>
|
||||
<log>Rilasciato il nuovo player video.</log>
|
||||
<log>Inserimento dell'emittente RC105TV nella lista delle WebTV.</log>
|
||||
<log>Rilasciato il nuovo player video</log>
|
||||
<log>Inserimento dell'emittente RC105TV nella lista delle WebTV</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -246,9 +161,9 @@
|
||||
<version>
|
||||
<number>0.22.4 Beta</number>
|
||||
<logs>
|
||||
<log>Correzione errori minimi nel sistema.</log>
|
||||
<log>Aggiunta indicatore della versione app nella schermata desktop.</log>
|
||||
<log>Preparazione player video - Correzioni minimi player e aggiunta di pagine mancanti.</log>
|
||||
<log>Correzione errori minimi nel sistema</log>
|
||||
<log>Aggiunta indicatore della versione app nella schermata desktop</log>
|
||||
<log>Preparazione player video - Correzioni minimi player e aggiunta di pagine mancanti</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -256,8 +171,8 @@
|
||||
<version>
|
||||
<number>0.22.3 Beta</number>
|
||||
<logs>
|
||||
<log>Migliorati i tempi di caricamento dei player.</log>
|
||||
<log>Aggiunta nuovi file di Configurazione.</log>
|
||||
<log>Migliorati i tempi di caricamento dei player</log>
|
||||
<log>Aggiunta nuovi file di Configurazione</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
@@ -275,8 +190,8 @@
|
||||
<version>
|
||||
<number>0.22.1 Beta</number>
|
||||
<logs>
|
||||
<log>Corretto il bug del logo all'interno dell'homepage.</log>
|
||||
<log>Corretto la riproduzione audio dell'emittente Radio Città 105.</log>
|
||||
<log>Corretto il bug del logo all'interno dell'homepage</log>
|
||||
<log>Corretto la riproduzione audio dell'emittente Radio Città 105</log>
|
||||
<log>Correzione e bugfix di problematiche varie.</log>
|
||||
</logs>
|
||||
</version>
|
||||
|
||||
Binary file not shown.
+5
-7
@@ -8,10 +8,9 @@
|
||||
<slogan>O Sei Fuori, O Sei Dei Nostri</slogan>
|
||||
<thematic>false</thematic>
|
||||
<logo>https://i0.wp.com/www.radiodiffusionelibera.com/wp-content/uploads/2017/01/RDL-Facebook.png</logo>
|
||||
<stream>https://asvradiostream.asvstudios.it/radio/8000/radio.aac</stream>
|
||||
<stream>https://asvradiostream.asvstudios.it/radio/8000/radio.mp3</stream>
|
||||
<streamhls>https://srvone.radio.asvhosting.com/hls/rdlradio/live.m3u8</streamhls>
|
||||
<contentplayer>https://www.radiodiffusionelibera.com/contentrpigplay</contentplayer>
|
||||
<apiradio>https://srvone.radio.asvhosting.com/api/nowplaying/2</apiradio>
|
||||
</station>
|
||||
|
||||
<station>
|
||||
@@ -23,10 +22,9 @@
|
||||
<stream>https://asvradiostream.asvstudios.it/radio/8020/auto.aac</stream>
|
||||
<streamhls>https://srvone.radio.asvhosting.com/hls/radiocitta105/live.m3u8</streamhls>
|
||||
<contentplayer>https://www.radiocitta105.it/contentrpigplay</contentplayer>
|
||||
<apiradio>https://srvone.radio.asvhosting.com/api/nowplaying/1</apiradio>
|
||||
</station>
|
||||
|
||||
<!-- <station>
|
||||
<station>
|
||||
<id>3</id>
|
||||
<name>RadioAI</name>
|
||||
<slogan>Solo musica AI - Powered by RDL </slogan>
|
||||
@@ -35,7 +33,7 @@
|
||||
<stream>https://srvone.radio.asvhosting.com/listen/radioai/radio.mp3</stream>
|
||||
<streamhls>https://srvone.radio.asvhosting.com/hls/radioai/live.m3u8</streamhls>
|
||||
<contentplayer></contentplayer>
|
||||
</station> -->
|
||||
</station>
|
||||
|
||||
<!-- <station>
|
||||
<id>4</id>
|
||||
@@ -48,7 +46,7 @@
|
||||
<contentplayer></contentplayer>
|
||||
</station> -->
|
||||
|
||||
<!-- <station>
|
||||
<station>
|
||||
<id>5</id>
|
||||
<name>Radio People Italy</name>
|
||||
<slogan>La radio della Gente</slogan>
|
||||
@@ -57,6 +55,6 @@
|
||||
<stream></stream>
|
||||
<streamhls></streamhls>
|
||||
<contentplayer>https://www.rpigroup.it/radiopeopleitaly_contentrpigroup/</contentplayer>
|
||||
</station> -->
|
||||
</station>
|
||||
|
||||
</radio>
|
||||
Binary file not shown.
+2
-2
@@ -14,8 +14,8 @@
|
||||
<id>1</id>
|
||||
<name>Rc105 TV</name>
|
||||
<logo>https://www.radiocitta105.it/wp-content/uploads/2020/06/26168468_1590103344416186_7025872599153073152_n-1.png</logo>
|
||||
<stream>https://tv.rpigroup.net/memfs/a9699134-efb3-4932-b8db-5a49ae214031.m3u8</stream>
|
||||
<poster>https://tv.rpigroup.net/memfs/a9699134-efb3-4932-b8db-5a49ae214031.jpg</poster>
|
||||
<stream>https://webtv.rpigroup.it/e1e55a4b-abec-4043-8f08-e2105b48b59b.m3u8</stream>
|
||||
<poster>https://webtv.rpigroup.it/memfs/e1e55a4b-abec-4043-8f08-e2105b48b59b.jpg</poster>
|
||||
</station>
|
||||
|
||||
</tv>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,9 +5,6 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Author: A.S.V. Studios APPS
|
||||
# Website: https://app.rpigroup.net
|
||||
# Copyright (c) 2025-202 A.S.V. Studios APPS
|
||||
# ---------------------------------------------------------------
|
||||
# Questa app è disponibile all'interno della repository pubblica di RPIGroup Play.
|
||||
# ---------------------------------------------------------------
|
||||
# All Rights is reserved by A.S.V. Studios APPS.
|
||||
#
|
||||
|
||||
Binary file not shown.
@@ -6,8 +6,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
let hlsInstance = null;
|
||||
let currentXHR = null;
|
||||
let isLoading = false;
|
||||
let loadingOverlay = null;
|
||||
let metadataInterval = null;
|
||||
|
||||
// WeakMap per tracciare i listener degli elementi
|
||||
const linkListeners = new WeakMap();
|
||||
@@ -57,12 +55,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
function cleanupPlayer() {
|
||||
console.log('Pulizia player audio...');
|
||||
|
||||
// Stop metadata updates
|
||||
if (metadataInterval) {
|
||||
clearInterval(metadataInterval);
|
||||
metadataInterval = null;
|
||||
}
|
||||
|
||||
// Distruggi istanza HLS
|
||||
if (hlsInstance) {
|
||||
try {
|
||||
@@ -102,27 +94,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostra l'overlay di caricamento
|
||||
*/
|
||||
function showLoadingOverlay() {
|
||||
if (!loadingOverlay) {
|
||||
loadingOverlay = document.getElementById('loadingOverlay');
|
||||
}
|
||||
if (loadingOverlay) {
|
||||
loadingOverlay.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nasconde l'overlay di caricamento
|
||||
*/
|
||||
function hideLoadingOverlay() {
|
||||
if (loadingOverlay) {
|
||||
loadingOverlay.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Caricamento pagina con protezione da race condition
|
||||
*/
|
||||
@@ -149,9 +120,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mostra l'overlay di caricamento
|
||||
showLoadingOverlay();
|
||||
|
||||
// Animazione fade out
|
||||
contentContainer.classList.remove('fade-in');
|
||||
contentContainer.classList.add('fade-out');
|
||||
@@ -170,9 +138,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (this.status === 200) {
|
||||
contentContainer.innerHTML = this.responseText;
|
||||
|
||||
// Nascondi overlay di caricamento
|
||||
hideLoadingOverlay();
|
||||
|
||||
// Animazione fade in
|
||||
contentContainer.classList.remove('fade-out');
|
||||
contentContainer.classList.add('fade-in');
|
||||
@@ -210,7 +175,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
console.log('Pagina caricata:', page);
|
||||
} else {
|
||||
hideLoadingOverlay();
|
||||
contentContainer.innerHTML = '<div class="content-page"><h2>Errore</h2><p>Impossibile caricare la pagina. Codice errore: ' + this.status + '</p></div>';
|
||||
contentContainer.classList.remove('fade-out');
|
||||
contentContainer.classList.add('fade-in');
|
||||
@@ -221,7 +185,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
currentXHR.onerror = function () {
|
||||
isLoading = false;
|
||||
currentXHR = null;
|
||||
hideLoadingOverlay();
|
||||
contentContainer.innerHTML = '<div class="content-page"><h2>Errore di connessione</h2><p>Controlla la tua connessione internet e riprova.</p></div>';
|
||||
contentContainer.classList.remove('fade-out');
|
||||
contentContainer.classList.add('fade-in');
|
||||
@@ -231,7 +194,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
currentXHR.onabort = function () {
|
||||
isLoading = false;
|
||||
currentXHR = null;
|
||||
hideLoadingOverlay();
|
||||
console.log('Richiesta XHR annullata');
|
||||
};
|
||||
|
||||
@@ -347,304 +309,228 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
*/
|
||||
|
||||
function initializePlayer() {
|
||||
console.log('Inizializzazione player audio (v2.1 - Format Toggle)...');
|
||||
console.log('Inizializzazione player audio...');
|
||||
|
||||
const playPauseBtn = document.getElementById('playPauseBtn');
|
||||
const playIcon = document.querySelector('.play-icon');
|
||||
const pauseIcon = document.querySelector('.pause-icon');
|
||||
const playerStatus = document.getElementById('playerStatus');
|
||||
const formatToggleBtn = document.getElementById('formatToggleBtn');
|
||||
const formatLabel = document.getElementById('formatLabel');
|
||||
const artistElement = document.getElementById('artist');
|
||||
|
||||
if (!playPauseBtn) return;
|
||||
if (!playPauseBtn) {
|
||||
console.error('Pulsante play/pause non trovato');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Cleanup Preventivo
|
||||
// Pulisci il player precedente
|
||||
cleanupPlayer();
|
||||
|
||||
// 2. Setup Elementi
|
||||
// Ottieni il nuovo audio player dal DOM
|
||||
audioPlayer = document.getElementById('hlsAudioPlayer');
|
||||
if (!audioPlayer) return;
|
||||
|
||||
if (!audioPlayer) {
|
||||
console.error('Elemento audio non trovato');
|
||||
return;
|
||||
}
|
||||
|
||||
const streamHLS = playPauseBtn.getAttribute('data-stream-hls');
|
||||
const streamFallback = playPauseBtn.getAttribute('data-stream-fallback');
|
||||
const stationName = playPauseBtn.getAttribute('data-station-name');
|
||||
const stationSlogan = playPauseBtn.getAttribute('data-station-slogan');
|
||||
const stationLogo = playPauseBtn.getAttribute('data-station-logo');
|
||||
|
||||
console.log('Stream HLS:', streamHLS);
|
||||
console.log('Stream Fallback:', streamFallback);
|
||||
console.log('Stazione:', stationName);
|
||||
|
||||
// Stato formato audio (preferenza salvata in localStorage)
|
||||
const storageKey = 'audioFormat_' + stationName;
|
||||
let currentFormat = localStorage.getItem(storageKey) || 'hls'; // 'hls' o 'direct'
|
||||
let isPlaying = false;
|
||||
|
||||
// Aggiorna label del formato
|
||||
function updateFormatLabel() {
|
||||
if (formatLabel) {
|
||||
formatLabel.textContent = currentFormat === 'hls' ? 'HLS' : 'MP3';
|
||||
}
|
||||
}
|
||||
updateFormatLabel();
|
||||
|
||||
// Configurazione HLS.js Ottimizzata per Qualità
|
||||
const hlsConfig = {
|
||||
debug: false,
|
||||
enableWorker: true,
|
||||
lowLatencyMode: false, // Disabilitato per stabilità e buffer migliore
|
||||
backBufferLength: 90,
|
||||
maxBufferLength: 30, // Aumentato buffer (default 30s)
|
||||
startLevel: -1, // Auto start
|
||||
xhrSetup: function (xhr, url) {
|
||||
xhr.withCredentials = false; // Fix CORS issues sometimes
|
||||
}
|
||||
};
|
||||
let streamType = 'hls'; // 'hls' o 'direct'
|
||||
|
||||
/**
|
||||
* Logica di Selezione Player
|
||||
* Priorità: HLS.js (PC/Android) > Nativo (iOS) > Fallback (Direct Stream)
|
||||
* Inizializza HLS stream
|
||||
*/
|
||||
function initStream(forceFormat = null) {
|
||||
const preferredFormat = forceFormat || currentFormat;
|
||||
|
||||
// Se l'utente ha scelto formato diretto, usa subito MP3/AAC
|
||||
if (preferredFormat === 'direct') {
|
||||
console.log('User preference: Direct stream (MP3/AAC)');
|
||||
useDirectStream();
|
||||
return;
|
||||
function initHLSStream() {
|
||||
if (!window.Hls) {
|
||||
console.error('HLS.js non caricato');
|
||||
return false;
|
||||
}
|
||||
|
||||
// STRATEGIA 1: HLS.js (Preferita per PC e Android)
|
||||
if (Hls.isSupported()) {
|
||||
console.log('Strategy: HLS.js (High Quality Control)');
|
||||
console.log('HLS supportato - uso HLS.js');
|
||||
|
||||
hlsInstance = new Hls({
|
||||
debug: false,
|
||||
enableWorker: true,
|
||||
lowLatencyMode: true,
|
||||
backBufferLength: 90
|
||||
});
|
||||
|
||||
hlsInstance = new Hls(hlsConfig);
|
||||
hlsInstance.loadSource(streamHLS);
|
||||
hlsInstance.attachMedia(audioPlayer);
|
||||
|
||||
hlsInstance.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
|
||||
console.log(`HLS Manifest Loaded. Levels: ${data.levels.length}`);
|
||||
|
||||
// Log dettagliato di tutti i livelli disponibili per debug
|
||||
data.levels.forEach((level, index) => {
|
||||
console.log(`Level ${index}: ${level.bitrate} bps (${(level.bitrate / 1000).toFixed(0)} kbps)`);
|
||||
hlsInstance.on(Hls.Events.MANIFEST_PARSED, function () {
|
||||
console.log('Manifest HLS caricato');
|
||||
audioPlayer.play().then(() => {
|
||||
console.log('Riproduzione HLS avviata');
|
||||
updatePlayState(true);
|
||||
}).catch(err => {
|
||||
console.error('Errore avvio riproduzione HLS:', err);
|
||||
tryFallbackStream();
|
||||
});
|
||||
|
||||
// CRITICAL: Forza partenza dal livello massimo per garantire qualità alta
|
||||
if (data.levels.length > 1) {
|
||||
const maxLevel = data.levels.length - 1;
|
||||
hlsInstance.startLevel = maxLevel;
|
||||
console.log(`✓ Forced START level to MAX: ${maxLevel} (${(data.levels[maxLevel].bitrate / 1000).toFixed(0)} kbps)`);
|
||||
}
|
||||
|
||||
attemptPlay();
|
||||
});
|
||||
|
||||
// Track quality switches per debug
|
||||
hlsInstance.on(Hls.Events.LEVEL_SWITCHING, function (event, data) {
|
||||
console.log(`→ Switching to level ${data.level}...`);
|
||||
});
|
||||
|
||||
hlsInstance.on(Hls.Events.LEVEL_SWITCHED, function (event, data) {
|
||||
const currentLevel = hlsInstance.levels[data.level];
|
||||
console.log(`✓ Switched to level ${data.level}: ${(currentLevel.bitrate / 1000).toFixed(0)} kbps`);
|
||||
});
|
||||
|
||||
hlsInstance.on(Hls.Events.ERROR, function (event, data) {
|
||||
console.error('Errore HLS:', data.type, data.details);
|
||||
if (data.fatal) {
|
||||
console.warn('HLS Fatal Error:', data.type);
|
||||
switch (data.type) {
|
||||
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||
hlsInstance.startLoad();
|
||||
console.log('Errore di rete, tentativo fallback...');
|
||||
tryFallbackStream();
|
||||
break;
|
||||
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||
console.log('Errore media, tentativo recupero...');
|
||||
hlsInstance.recoverMediaError();
|
||||
break;
|
||||
default:
|
||||
useDirectStream();
|
||||
console.log('Errore fatale, tentativo fallback...');
|
||||
tryFallbackStream();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// STRATEGIA 2: Nativo (Obbligatorio per iOS)
|
||||
if (audioPlayer.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
console.log('Strategy: Native HLS (iOS/Safari)');
|
||||
return true;
|
||||
} else if (audioPlayer.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
console.log('HLS nativo supportato');
|
||||
audioPlayer.src = streamHLS;
|
||||
audioPlayer.preload = 'auto'; // Suggerisce al browser di caricare dati
|
||||
|
||||
// Hack per iOS: Alcune volte serve un tocco utente, gestito dal click play
|
||||
attemptPlay();
|
||||
return;
|
||||
audioPlayer.play().then(() => {
|
||||
console.log('Riproduzione HLS nativa avviata');
|
||||
updatePlayState(true);
|
||||
}).catch(err => {
|
||||
console.error('Errore HLS nativo:', err);
|
||||
tryFallbackStream();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// STRATEGIA 3: Fallback (Stream MP3 diretto)
|
||||
console.log('Strategy: Direct Fallback');
|
||||
useDirectStream();
|
||||
return false;
|
||||
}
|
||||
|
||||
function useDirectStream() {
|
||||
/**
|
||||
* Usa stream diretto come fallback
|
||||
*/
|
||||
function tryFallbackStream() {
|
||||
console.log('Tentativo stream fallback:', streamFallback);
|
||||
|
||||
if (hlsInstance) {
|
||||
hlsInstance.destroy();
|
||||
hlsInstance = null;
|
||||
}
|
||||
console.log('Using direct stream:', streamFallback);
|
||||
|
||||
streamType = 'direct';
|
||||
audioPlayer.src = streamFallback;
|
||||
attemptPlay();
|
||||
audioPlayer.load();
|
||||
|
||||
audioPlayer.play().then(() => {
|
||||
console.log('Riproduzione stream diretto avviata');
|
||||
updatePlayState(true);
|
||||
}).catch(err => {
|
||||
console.error('Errore stream diretto:', err);
|
||||
updatePlayState(false);
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = 'Errore di riproduzione';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Funzione per cambiare formato
|
||||
function toggleFormat() {
|
||||
const wasPlaying = !audioPlayer.paused;
|
||||
/**
|
||||
* Aggiorna stato visuale play/pause
|
||||
*/
|
||||
function updatePlayState(playing) {
|
||||
isPlaying = playing;
|
||||
|
||||
// Cambia formato
|
||||
currentFormat = currentFormat === 'hls' ? 'direct' : 'hls';
|
||||
localStorage.setItem(storageKey, currentFormat);
|
||||
console.log('Switching to format:', currentFormat);
|
||||
|
||||
// Aggiorna label
|
||||
updateFormatLabel();
|
||||
|
||||
// Ferma riproduzione corrente
|
||||
if (audioPlayer) {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
|
||||
// Pulisci player precedente
|
||||
if (hlsInstance) {
|
||||
hlsInstance.destroy();
|
||||
hlsInstance = null;
|
||||
}
|
||||
audioPlayer.src = '';
|
||||
|
||||
// Reinizializza con nuovo formato
|
||||
initStream(currentFormat);
|
||||
|
||||
// Riprendi riproduzione se era in corso
|
||||
if (wasPlaying) {
|
||||
setTimeout(() => {
|
||||
togglePlay();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function attemptPlay() {
|
||||
// Nota: chiamare .play() senza interazione utente fallirà.
|
||||
// Questa funzione prepara lo stato. Il vero play avviene al click.
|
||||
if (playerStatus) playerStatus.textContent = 'Pronto alla riproduzione';
|
||||
}
|
||||
|
||||
function togglePlay() {
|
||||
if (audioPlayer.paused) {
|
||||
const playPromise = audioPlayer.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise.then(() => {
|
||||
updateUI(true);
|
||||
}).catch(error => {
|
||||
console.error('Play prevented:', error);
|
||||
// Se HLS fallisce al play (es. stale manifest), prova fallback
|
||||
if (!audioPlayer.src.includes(streamFallback) && !hlsInstance) {
|
||||
fallbackToDirectStream();
|
||||
audioPlayer.play().catch(e => console.error('Fallback failed:', e));
|
||||
}
|
||||
});
|
||||
if (playing) {
|
||||
playIcon.style.display = 'none';
|
||||
pauseIcon.style.display = 'inline-block';
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = 'In riproduzione...';
|
||||
}
|
||||
} else {
|
||||
playIcon.style.display = 'inline-block';
|
||||
pauseIcon.style.display = 'none';
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = stationSlogan || 'In pausa';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestione click play/pause
|
||||
*/
|
||||
playPauseBtn.addEventListener('click', function () {
|
||||
if (!audioPlayer) return;
|
||||
|
||||
if (isPlaying) {
|
||||
// Pausa
|
||||
audioPlayer.pause();
|
||||
updateUI(false);
|
||||
}
|
||||
}
|
||||
|
||||
function updateUI(playing) {
|
||||
isPlaying = playing;
|
||||
playIcon.style.display = playing ? 'none' : 'block';
|
||||
pauseIcon.style.display = playing ? 'block' : 'none';
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = playing ? 'In riproduzione' : 'In pausa';
|
||||
}
|
||||
}
|
||||
|
||||
// Listeners
|
||||
playPauseBtn.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
// Se non inizializzato (primo click), avvia stream
|
||||
if (!audioPlayer.src && !hlsInstance) {
|
||||
initStream();
|
||||
// Piccolo timeout per dare tempo al setup prima del play effettivo
|
||||
setTimeout(togglePlay, 50);
|
||||
updatePlayState(false);
|
||||
console.log('Riproduzione in pausa');
|
||||
} else {
|
||||
togglePlay();
|
||||
// Play
|
||||
if (!audioPlayer.src && !hlsInstance) {
|
||||
// Prima riproduzione - inizializza lo stream
|
||||
if (streamHLS && !initHLSStream()) {
|
||||
// Se HLS fallisce, usa direttamente il fallback
|
||||
tryFallbackStream();
|
||||
}
|
||||
} else {
|
||||
// Riprendi riproduzione
|
||||
audioPlayer.play().then(() => {
|
||||
updatePlayState(true);
|
||||
console.log('Riproduzione ripresa');
|
||||
}).catch(err => {
|
||||
console.error('Errore ripresa riproduzione:', err);
|
||||
updatePlayState(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
audioPlayer.onplay = () => updateUI(true);
|
||||
audioPlayer.onpause = () => updateUI(false);
|
||||
/**
|
||||
* Event listeners audio player
|
||||
*/
|
||||
audioPlayer.addEventListener('play', function () {
|
||||
updatePlayState(true);
|
||||
});
|
||||
|
||||
audioPlayer.onerror = (e) => {
|
||||
console.error('Audio Error:', audioPlayer.error);
|
||||
if (playerStatus) playerStatus.textContent = 'Errore riproduzione';
|
||||
updateUI(false);
|
||||
};
|
||||
audioPlayer.addEventListener('pause', function () {
|
||||
updatePlayState(false);
|
||||
});
|
||||
|
||||
// Format toggle button listener
|
||||
if (formatToggleBtn) {
|
||||
formatToggleBtn.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
toggleFormat();
|
||||
};
|
||||
}
|
||||
audioPlayer.addEventListener('error', function (e) {
|
||||
console.error('Errore audio player:', e);
|
||||
updatePlayState(false);
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = 'Errore di riproduzione';
|
||||
}
|
||||
});
|
||||
|
||||
audioPlayer.addEventListener('waiting', function () {
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = 'Buffering...';
|
||||
}
|
||||
});
|
||||
|
||||
audioPlayer.addEventListener('playing', function () {
|
||||
if (playerStatus) {
|
||||
playerStatus.textContent = 'In riproduzione...';
|
||||
}
|
||||
});
|
||||
|
||||
// Setup Media Session
|
||||
setupMediaSession(stationName, playPauseBtn.getAttribute('data-station-slogan'), playPauseBtn.getAttribute('data-station-logo'), playIcon, pauseIcon);
|
||||
setupMediaSession(stationName, stationSlogan, stationLogo, playIcon, pauseIcon);
|
||||
|
||||
// --- GESTIONE METADATI (Now Playing) ---
|
||||
const apiUrl = playPauseBtn.getAttribute('data-api-url');
|
||||
if (apiUrl) {
|
||||
console.log('Starting metadata polling for:', apiUrl);
|
||||
|
||||
function updateMetadata() {
|
||||
fetch(apiUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.now_playing && data.now_playing.song) {
|
||||
const song = data.now_playing.song;
|
||||
|
||||
// Aggiorna DOM
|
||||
const songsEl = document.getElementById('songs');
|
||||
const artistEl = document.getElementById('artist');
|
||||
const albumArtEl = document.getElementById('albumsong');
|
||||
|
||||
if (songsEl) songsEl.textContent = song.title;
|
||||
if (artistEl) artistEl.textContent = song.artist;
|
||||
if (albumArtEl && song.art) {
|
||||
// Evita refresh se l'immagine è la stessa
|
||||
if (albumArtEl.src !== song.art) {
|
||||
albumArtEl.src = song.art;
|
||||
}
|
||||
}
|
||||
|
||||
// Aggiorna Media Session
|
||||
if ('mediaSession' in navigator) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: song.title,
|
||||
artist: song.artist,
|
||||
album: stationName,
|
||||
artwork: [
|
||||
{ src: song.art || playPauseBtn.getAttribute('data-station-logo'), sizes: '512x512', type: 'image/png' }
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error('Error fetching metadata:', err));
|
||||
}
|
||||
|
||||
// Chiamata immediata
|
||||
updateMetadata();
|
||||
|
||||
// Polling ogni 10 secondi
|
||||
metadataInterval = setInterval(updateMetadata, 10000);
|
||||
}
|
||||
|
||||
console.log('Player System Ready with format toggle.');
|
||||
console.log('Player audio inizializzato');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -652,127 +538,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
*/
|
||||
function initializeTVPlayer() {
|
||||
console.log('TV Player inizializzato');
|
||||
|
||||
const video = document.getElementById('tvVideoPlayer');
|
||||
if (!video) {
|
||||
console.log('Elemento video TV non trovato');
|
||||
return;
|
||||
}
|
||||
|
||||
// Cleanup istanza precedente se esiste
|
||||
if (video.hlsInstance) {
|
||||
video.hlsInstance.destroy();
|
||||
delete video.hlsInstance;
|
||||
}
|
||||
|
||||
const videoSrc = video.getAttribute('data-src');
|
||||
console.log('Video Source:', videoSrc);
|
||||
|
||||
if (!videoSrc) {
|
||||
console.error('Nessuna sorgente video specificata in data-src');
|
||||
return;
|
||||
}
|
||||
|
||||
// Creazione elemento per errori se non esiste già
|
||||
let errorDisplay = video.parentNode.querySelector('.tv-error-display');
|
||||
if (!errorDisplay) {
|
||||
errorDisplay = document.createElement('div');
|
||||
errorDisplay.className = 'tv-error-display';
|
||||
errorDisplay.style.display = 'none';
|
||||
errorDisplay.style.position = 'absolute';
|
||||
errorDisplay.style.top = '50%';
|
||||
errorDisplay.style.left = '50%';
|
||||
errorDisplay.style.transform = 'translate(-50%, -50%)';
|
||||
errorDisplay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
|
||||
errorDisplay.style.color = '#fff';
|
||||
errorDisplay.style.padding = '20px';
|
||||
errorDisplay.style.borderRadius = '8px';
|
||||
errorDisplay.style.textAlign = 'center';
|
||||
errorDisplay.style.zIndex = '2000';
|
||||
errorDisplay.style.maxWidth = '90%';
|
||||
if (video.parentNode) {
|
||||
video.parentNode.appendChild(errorDisplay);
|
||||
// Assicurati che il parent sia relative per il posizionamento absolute
|
||||
if (getComputedStyle(video.parentNode).position === 'static') {
|
||||
video.parentNode.style.position = 'relative';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showError(msg, details) {
|
||||
console.error(msg, details);
|
||||
errorDisplay.innerHTML = '<strong>Errore:</strong><br>' + msg + (details ? '<br><small>' + details + '</small>' : '');
|
||||
errorDisplay.style.display = 'block';
|
||||
}
|
||||
|
||||
// Controllo libreria HLS
|
||||
if (typeof Hls === 'undefined') {
|
||||
// Riprova tra poco se magari sta ancora caricando
|
||||
setTimeout(() => {
|
||||
if (typeof Hls === 'undefined') {
|
||||
showError('Libreria HLS non caricata correttamente.');
|
||||
} else {
|
||||
initializeTVPlayer(); // Riprova inizializzazione
|
||||
}
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Hls.isSupported()) {
|
||||
console.log('HLS Supported - Loading stream');
|
||||
var hls = new Hls({
|
||||
debug: false,
|
||||
enableWorker: true
|
||||
});
|
||||
|
||||
hls.loadSource(videoSrc);
|
||||
hls.attachMedia(video);
|
||||
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, function () {
|
||||
console.log('TV Manifest Parsed - Ready to play');
|
||||
var playPromise = video.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise.catch(error => {
|
||||
console.log('Autoplay blocked or failed:', error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Gestione errori estesa
|
||||
hls.on(Hls.Events.ERROR, function (event, data) {
|
||||
console.warn('HLS Error:', data);
|
||||
if (data.fatal) {
|
||||
switch (data.type) {
|
||||
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||
console.log('Network error, recovering...');
|
||||
hls.startLoad();
|
||||
break;
|
||||
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||
console.log('Media error, recovering...');
|
||||
hls.recoverMediaError();
|
||||
break;
|
||||
default:
|
||||
showError('Errore fatale riproduzione.', data.type);
|
||||
hls.destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
video.hlsInstance = hls;
|
||||
|
||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
console.log('Native HLS Supported (Safari/iOS)');
|
||||
video.src = videoSrc;
|
||||
video.addEventListener('loadedmetadata', function () {
|
||||
video.play().catch(e => console.log("Autoplay iOS prevented"));
|
||||
});
|
||||
video.addEventListener('error', function (e) {
|
||||
showError('Errore riproduzione nativa.', e.message);
|
||||
});
|
||||
} else {
|
||||
showError('Il tuo browser non supporta HLS.');
|
||||
}
|
||||
// Implementare logica specifica per TV se necessario
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -910,8 +676,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const pathWithoutBase = currentPath.replace(BASE_PATH, '').replace(/^\//, '');
|
||||
const redirectParam = pathWithoutBase ? '&redirect=' + encodeURIComponent(pathWithoutBase) : '';
|
||||
|
||||
const width = 400;
|
||||
const height = 840;
|
||||
const width = 375;
|
||||
const height = 667;
|
||||
const left = (window.screen.width / 2) - (width / 2);
|
||||
const top = (window.screen.height / 2) - (height / 2);
|
||||
|
||||
@@ -947,7 +713,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
* Setup modalità standalone (PWA)
|
||||
*/
|
||||
function setupStandaloneMode() {
|
||||
const appContainer = document.querySelector('.container') || document.querySelector('.container-fluid');
|
||||
const appContainer = document.querySelector('.container');
|
||||
if (!appContainer) return;
|
||||
|
||||
if (window.opener && !window.opener.closed) {
|
||||
@@ -980,69 +746,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (currentPage === 'page/contact') {
|
||||
setTimeout(() => initializeContactForm(), 100);
|
||||
}
|
||||
|
||||
if (currentPage === 'podcast') {
|
||||
// Reset visualizzazione podcast quando si cambia pagina e si torna
|
||||
if (typeof window.closePodcast === 'function') {
|
||||
window.closePodcast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestione Podcast (Global Functions)
|
||||
*/
|
||||
window.openPodcast = function (url, title) {
|
||||
console.log('Apertura podcast:', title, url);
|
||||
const list = document.getElementById('podcast-list');
|
||||
const detail = document.getElementById('podcast-detail');
|
||||
const iframe = document.getElementById('podcast-iframe');
|
||||
const homeNav = document.getElementById('home-navigation');
|
||||
const podNav = document.getElementById('podcast-header');
|
||||
const scrollContainer = document.querySelector('main');
|
||||
|
||||
if (!list || !detail || !iframe) {
|
||||
console.error('Elementi podcast non trovati nel DOM');
|
||||
return;
|
||||
}
|
||||
|
||||
// Caricamento iframe
|
||||
iframe.src = url;
|
||||
|
||||
// Cambio vista
|
||||
podNav.style.display = 'none';
|
||||
list.style.display = 'none';
|
||||
detail.style.display = 'block';
|
||||
if (homeNav) homeNav.style.display = 'none';
|
||||
|
||||
// Scroll in alto
|
||||
if (scrollContainer) {
|
||||
scrollContainer.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
} else {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
window.closePodcast = function () {
|
||||
console.log('Chiusura podcast');
|
||||
const list = document.getElementById('podcast-list');
|
||||
const detail = document.getElementById('podcast-detail');
|
||||
const iframe = document.getElementById('podcast-iframe');
|
||||
const podNav = document.getElementById('podcast-header');
|
||||
const homeNav = document.getElementById('home-navigation');
|
||||
|
||||
if (!list || !detail || !iframe) return;
|
||||
|
||||
// Svuota iframe per fermare audio/video
|
||||
iframe.src = 'about:blank';
|
||||
|
||||
// Cambio vista
|
||||
podNav.style.display = 'block';
|
||||
list.style.display = 'block';
|
||||
detail.style.display = 'none';
|
||||
if (homeNav) homeNav.style.display = 'block';
|
||||
};
|
||||
|
||||
/**
|
||||
* Inizializzazione principale
|
||||
*/
|
||||
@@ -1051,7 +756,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
setupOpenAppButton();
|
||||
|
||||
if (document.querySelector('.container') || document.querySelector('.container-fluid')) {
|
||||
if (document.querySelector('.container')) {
|
||||
setupStandaloneMode();
|
||||
attachLinkListeners();
|
||||
setupHistoryNavigation();
|
||||
|
||||
Binary file not shown.
Vendored
-7
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
+5
-13
@@ -11,11 +11,11 @@
|
||||
<a href="<?php echo $base_path; ?>/" data-page="home" class="navLink <?php echo $page == 'home' ? 'active' : ''; ?>">Home</a>
|
||||
<a href="<?php echo $base_path; ?>/radio" data-page="radio" class="navLink <?php echo ($page == 'radio' || $page == 'play') ? 'active' : ''; ?>">Radio</a>
|
||||
<a href="<?php echo $base_path; ?>/tv" data-page="tv" class="navLink <?php echo ($page == 'tv' || $page == 'playtv') ? 'active' : ''; ?>">TV</a>
|
||||
<a href="<?php echo $base_path; ?>/podcast" data-page="podcast" class="navLink <?php echo ($page == 'page' && $param == 'addradio') ? 'active' : ''; ?>">Podcast</a>
|
||||
<a href="<?php echo $base_path; ?>/page/addradio" data-page="page/addradio" class="navLink <?php echo ($page == 'page' && $param == 'addradio') ? 'active' : ''; ?>">Add Radio</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="container-fluid" id="content">
|
||||
<main class="container" id="content">
|
||||
<?php
|
||||
// Carica il contenuto iniziale in base all'URL
|
||||
switch ($page) {
|
||||
@@ -56,9 +56,6 @@
|
||||
include './pages/page/home.php';
|
||||
}
|
||||
break;
|
||||
case 'podcast':
|
||||
include './pages/page/podcast.php';
|
||||
break;
|
||||
case 'page':
|
||||
if (!empty($param)) {
|
||||
switch ($param) {
|
||||
@@ -68,6 +65,9 @@
|
||||
case 'copyright':
|
||||
include './pages/page/copyright.php';
|
||||
break;
|
||||
case 'addradio':
|
||||
include './pages/page/addradio.php';
|
||||
break;
|
||||
case 'contact':
|
||||
include './pages/page/contact.php';
|
||||
break;
|
||||
@@ -93,14 +93,6 @@
|
||||
?>
|
||||
</main>
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
<div id="loadingOverlay" class="loading-overlay">
|
||||
<div class="loading-content">
|
||||
<div class="spinner-large"></div>
|
||||
<p class="loading-text">Caricamento...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="menu-section">
|
||||
<a href="<?php echo $base_path; ?>/page/termini-condizioni" data-page="page/termini-condizioni" class="navLink">Termini e Condizioni</a> •
|
||||
|
||||
Binary file not shown.
+9
-9
@@ -1,12 +1,12 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: relative;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Pagina non trovata</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="titlePage">Pagina non trovata</h1>
|
||||
|
||||
<p class="text-center">La pagina che hai provato a cercare non esiste o non è disponibile.</p>
|
||||
<p class="text-center">La pagina che hai provato a cercare non esiste o non è disponibile.</p>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+12
-31
@@ -1,35 +1,16 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Come funziona l'app</span>
|
||||
</div>
|
||||
<h1 class="titlePage">Come funziona RPIGroup Play?</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<p>La pagina è in fase di realizzazione... Attendi il prossimo aggiornamento per leggere le nostre istruzioni d'uso!</p>
|
||||
</div>
|
||||
|
||||
<div class="tec px-4">
|
||||
<p>RPIGroup Play è l'applicazione che permette di ascoltare le radio e le webtv preferite in un unico luogo.</p>
|
||||
<p>Per utilizzare l'applicazione, basta semplicemente entrare nell'applicazione dal link app.rpigroup.it, selezionare la sezione Radio o TV e scegliere la radio o la webtv che desideri ascoltare.</p>
|
||||
<br>
|
||||
<p>
|
||||
<b>Come installare l'app?</b></br>
|
||||
Per installare l'applicazione, basta semplicemente entrare nell'applicazione dal link app.rpigroup.it e cliccare sull'icona "Aggiungi all'Home". Oppure, per gli utenti iOS, entrando da safari dal link app.rpigroup.it, cliccare sull'icona "Convididi", scendere alla voce "Aggiungi all'Home" e cliccare su "Aggiungi all'Home".
|
||||
</p>
|
||||
<br>
|
||||
<br><br>
|
||||
<h2 class="text-start titlePage">F.A.Q.</h2>
|
||||
<p>
|
||||
<b>Posso scaricarla da Google Play Store e Apple App Store?</b></br>
|
||||
Non è possibile al momento scaricare l'applicazione da Google Play Store e Apple App Store.
|
||||
</p>
|
||||
<p>
|
||||
<b>Posso utilizzare l'applicazione su un computer?</b></br>
|
||||
Sì, dal tuo browser preferito, visita la pagina app.rpigroup.it. L'applicazione è anche installabile, cliccando sulla icona dedicata all'installazione della PWA.
|
||||
</p>
|
||||
<p>
|
||||
<b>Posso aggiungere la mia stazione radio preferita?</b></br>
|
||||
Sì, cliccando sul pulsante "Aggiungi Radio" nella sezione Radio, potrai aggiungere la tua stazione radio preferita compilando il form dedicato.
|
||||
</p>
|
||||
</div>
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<h1 class="titlePage">Aggiungi la tua radio</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<p>Al momento, il modulo è temporaneamente chiuso</p>
|
||||
<p>Ti invitiamo a controllare più tardi oppure, attendi l'uscita di un prossimo aggiornamento!</p>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
@@ -1,17 +1,7 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white; z-index: 2;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Changelog</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-4">
|
||||
|
||||
<p class="text-center" style="font-size: 0.9rem; font-weight: 300;">Codice dell'app visionabile su <a href="https://git.asv.ovh/asvstudiosapps/rpigroupplay" target="_blank" style="font-weight: 500;">ASV Git</a></p>
|
||||
<h1 class="titlePage">Changelog</h1>
|
||||
<p class="subtitlePage">Visualizza tutti gli aggiornamenti ricevuti</p>
|
||||
|
||||
<?php
|
||||
// Verifica che $changelog sia stato caricato correttamente in getStation.inc.php
|
||||
@@ -39,4 +29,9 @@ if (isset($changelog) && $changelog !== false && isset($changelog->version)) {
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+12
-10
@@ -39,15 +39,17 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Contatti</span>
|
||||
</div>
|
||||
<h1 class="titlePage">Contatti</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<p>La pagina è in fase di realizzazione... Attendi il prossimo aggiornamento per leggere le nostre istruzioni d'uso!</p>
|
||||
</div>
|
||||
|
||||
<div class="tec px-4">
|
||||
<p>La pagina è in fase di realizzazione... Attendi il prossimo aggiornamento per leggere le nostre istruzioni d'uso!</p>
|
||||
</div>
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+13
-10
@@ -1,17 +1,20 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Diritti D'Autore</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="titlePage">Diritti d'Autore</h1>
|
||||
<p class="subtitlePage">Come funziona e chi lo gestisce</p>
|
||||
|
||||
<div class="tec px-4">
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<p>RPIGroup è un player audio e video, che aggrega i flussi audio in streaming di emittenti iscritte all'interno del gruppo RPIGroup.</p>
|
||||
<p>I flussi presenti all'interno della seguente app non provvengono direttamente da quest'ultima, ma dal sito web dell'emittente stessa.</p>
|
||||
<p>L'applicazione funge come semplice ripetitore audio. Per tanto, i diritti musicali sono a carico dell'emittente presente nell'app, inserendo all'interno della pagina dedicata alle informazioni sulla trasmissione, i numeri licenze dei diritti d'autore e discografici dei brani trasmessi.</p>
|
||||
<p>Pertanto, se si ritiene che una delle emittenti non ha le licenze per la diffusione dei brani, invitiamo al segnalante di inoltrare una mail ad <a href="mailto:abuse@asvhosting.com">abuse@asvhosting.com</a> per la rimozione definitiva dell'emittente.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+60
-113
@@ -1,114 +1,61 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<h1 class="titlePage">Benvenuto</h1>
|
||||
<p class="subtitlePage">nella nuova RPIGroup Play</p>
|
||||
|
||||
<div class="row g-2 mb-4 px-4" style="width: 100%">
|
||||
<div class="col-6">
|
||||
<a href="<?php echo $base_path; ?>/radio" data-page="radio" class="linkBox">
|
||||
<div class="clickBox Squared">
|
||||
<img src="<?=$base_path?>/img/radio.png" alt="Radio">
|
||||
<p class="m-0 p-0">Radio</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="<?php echo $base_path; ?>/tv" data-page="tv" class="linkBox">
|
||||
<div class="clickBox Squared">
|
||||
<img src="<?=$base_path?>/img/tv.png" alt="tv">
|
||||
<p class="m-0 p-0">TV</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<a href="<?php echo $base_path; ?>/podcast" data-page="podcast" class="linkBox">
|
||||
<div class="clickBox Squared">
|
||||
<p class="m-0 p-0">PODCAST</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.content-adv{
|
||||
text-align: center;
|
||||
background: #3849a8;
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.content-adv:before{
|
||||
content: "ADV";
|
||||
position: relative;
|
||||
background: #f7b835;
|
||||
padding: 3px 10px;
|
||||
font-size: 0.8rem;
|
||||
border-radius: 27px;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
top: -10px;
|
||||
margin: 0;
|
||||
}
|
||||
.content-adv img{
|
||||
max-width: 100%;
|
||||
border-radius: 10px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.content-adv p{
|
||||
color: white;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- <div class="content-adv mb-4 hiddenApp">
|
||||
<a href="https://play.google.com/apps/testing/it.asvstudios.rpigroupplay" target="_blank" class="">
|
||||
<img src="https://play.google.com/intl/it_IT/badges/static/images/badges/en_badge_web_generic.png" alt="Google Play Store">
|
||||
<p>Entra nel programma di beta testing di RPIGroup Play per Google Play Store (Android)</p>
|
||||
<p style="font-size: 10px; margin-top: 15px; text-decoration: underline;">Clicca qui per scoprire di più</p>
|
||||
</a>
|
||||
</div> -->
|
||||
|
||||
|
||||
<div class="row g-2 mb-4 px-4" style="width: 100%">
|
||||
<div class="col-12">
|
||||
<a href="https://www.co-municare.it" target="_blank" class="">
|
||||
<div class="clickBox p-2">
|
||||
<img src="https://www.co-municare.it/wp-content/uploads/2025/01/newlogo_co-municare-it.png" alt="logo Co-Municare.it">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/about" data-page="page/about" class="linkBox">
|
||||
<div class="clickBox">
|
||||
Come<br>funziona?
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/copyright" data-page="page/copyright" class="linkBox">
|
||||
<div class="clickBox">
|
||||
Diritti<br>d'Autore
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/contact" data-page="page/contact" class="linkBox">
|
||||
<div class="clickBox">
|
||||
I nostri<br>Contatti
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-4 px-4" style="width: 100%">
|
||||
<div class="col-12">
|
||||
<a href="https://drive.asv.ovh/apps/forms/s/Zfk8cJk3oCz2Y2dHyWdEcgL7" target="_blank" class="linkBox">
|
||||
<div class="clickBox p-2">
|
||||
Lascia un feedback
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<h1 class="titlePage">Benvenuto</h1>
|
||||
<p class="subtitlePage">nella nuova RPIGroup Play</p>
|
||||
|
||||
<div class="row g-2 mb-4">
|
||||
<div class="col-6">
|
||||
<a href="<?php echo $base_path; ?>/radio" data-page="radio" class="linkBox">
|
||||
<div class="clickBox Squared">
|
||||
<img src="<?=$base_path?>/img/radio.png" alt="Radio">
|
||||
<p class="m-0 p-0">Radio</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="<?php echo $base_path; ?>/tv" data-page="tv" class="linkBox">
|
||||
<div class="clickBox Squared">
|
||||
<img src="<?=$base_path?>/img/tv.png" alt="tv">
|
||||
<p class="m-0 p-0">TV</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-4">
|
||||
<div class="col-12">
|
||||
<a href="https://www.co-municare.it" target="_blank" class="">
|
||||
<div class="clickBox p-2">
|
||||
<img src="https://www.co-municare.it/wp-content/uploads/2025/01/newlogo_co-municare-it.png" alt="logo Co-Municare.it">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<a href="<?php echo $base_path; ?>/page/addradio" data-page="page/addradio" class="linkBox">
|
||||
<div class="clickBox p-2">
|
||||
Aggiungi la tua radio
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/about" data-page="page/about" class="linkBox">
|
||||
<div class="clickBox">
|
||||
Come funziona?
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/copyright" data-page="page/copyright" class="linkBox">
|
||||
<div class="clickBox">
|
||||
Diritti<br>d'Autore
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="<?php echo $base_path; ?>/page/contact" data-page="page/contact" class="linkBox">
|
||||
<div class="clickBox">
|
||||
I nostri<br>Contatti
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
Binary file not shown.
+53
-93
@@ -1,102 +1,62 @@
|
||||
<?php
|
||||
|
||||
$station_id = (string)$station->id;
|
||||
$station_name = (string)$station->name;
|
||||
$station_slogan = (string)$station->slogan;
|
||||
$station_logo = (string)$station->logo;
|
||||
$station_stream = (string)$station->stream;
|
||||
$station_streamhls = (string)$station->streamhls;
|
||||
$station_contentplayer = (string)$station->contentplayer;
|
||||
$station_apiradio = (string)$station->apiradio;
|
||||
|
||||
<?php
|
||||
if($station->contentplayer == ""){
|
||||
?>
|
||||
<style>
|
||||
.staticpage{
|
||||
background: linear-gradient(45deg, #3849a8, #f7b835);
|
||||
padding: 22px 35px 10px 35px;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
height: calc(100vh - 312px);
|
||||
color: white;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.staticpage > .logo{
|
||||
width: 200px;
|
||||
border-radius: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.staticpage > p{
|
||||
margin: 0;
|
||||
}
|
||||
.staticpage > p.titleRadio{
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
<div class="staticpage">
|
||||
<img src="<?php echo $station->logo; ?>" class="logo" alt="logo radio">
|
||||
<p class="titleRadio"><?php echo $station->name; ?></p>
|
||||
<p class="subtitleRadio"><?php echo $station->slogan; ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}else{
|
||||
?>
|
||||
<iframe src="<?php echo $station->contentplayer; ?>" class="contentplayer" frameborder="0"></iframe>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="radio-player-container" style="background-color: #ffffff;height: calc(100% - <?php if($is_mobile){ echo "232px"; }else{ echo "217px"; } ?>);position: absolute;left: calc(50%);display: flex;flex-direction: column;max-width: 750px;transform: translateX(-50%);width: 100%;">
|
||||
|
||||
<div class="radio-header" style="padding: 20px; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/radio" data-page="radio" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;"><?php echo $station_name; ?></span>
|
||||
<div class="footer_player" <?php if($is_mobile){ ?> style="bottom: 84px;" <? } ?>>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-2" style="width: 70px;">
|
||||
<img src="<?php echo $station->logo; ?>" alt="<?php echo $station->name; ?>" style="width: 60px;">
|
||||
</div>
|
||||
|
||||
<?php if(!empty($station_logo)): ?>
|
||||
<div class="right-controls">
|
||||
<img src="<?php echo $station_logo; ?>" alt="Logo" style="height: 30px; width: auto;">
|
||||
<div class="col">
|
||||
<div id="artist" style="font-weight: 700; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;"><?php echo $station->name; ?></div>
|
||||
<div id="playerStatus" style="text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical ;overflow: hidden;"><?php echo $station->slogan; ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if($station->contentplayer == ""){
|
||||
?>
|
||||
<style>
|
||||
.staticpage{
|
||||
background: linear-gradient(45deg, #3849a8, #f7b835);
|
||||
padding: 22px 35px 10px 35px;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
height: calc(100vh - 393px);
|
||||
color: white;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
}
|
||||
.staticpage > .logo{
|
||||
width: 200px;
|
||||
border-radius: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.staticpage > p{
|
||||
margin: 0;
|
||||
}
|
||||
.staticpage > p.titleRadio{
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
<div class="staticpage">
|
||||
<img src="<?php echo $station->logo; ?>" class="logo" alt="logo radio">
|
||||
<p class="titleRadio"><?php echo $station->name; ?></p>
|
||||
<p class="subtitleRadio"><?php echo $station->slogan; ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}else{
|
||||
?>
|
||||
<iframe src="<?=$station_contentplayer?>" class="contentplayer" frameborder="0"></iframe>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="footer_player">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-2" style="width: 70px;">
|
||||
<img id="albumsong" src="<?php echo $station->logo; ?>" alt="<?php echo $station->name; ?>" style="width: 60px;height: 60px;">
|
||||
</div>
|
||||
<div class="col">
|
||||
<div id="songs" style="font-weight: 700; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;"><?php echo $station->name; ?></div>
|
||||
<div id="artist" style="text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical ;overflow: hidden;"><?php echo $station->slogan; ?></div>
|
||||
</div>
|
||||
<div class="col-auto" style="text-align: center; margin-top: 1px; padding-right: 0;">
|
||||
<button id="formatToggleBtn" title="Cambia formato audio">
|
||||
<span id="formatLabel" style="font-size: 12px;font-weight: 600;border-radius: 6px;border: 2px solid #ffffff;padding: 4px 6px;background: rgba(247, 184, 53, 0.3);color: #2a377e;">HLS</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-2" style="text-align: center; margin-top: 1px; margin-right: 5px; width: 67px;">
|
||||
<button id="playPauseBtn"
|
||||
data-stream-hls="<?php echo $station->streamhls; ?>"
|
||||
data-stream-fallback="<?php echo $station->stream; ?>"
|
||||
data-station-name="<?php echo htmlspecialchars($station->name); ?>"
|
||||
data-station-logo="<?php echo $station->logo; ?>"
|
||||
data-station-slogan="<?php echo htmlspecialchars($station->slogan); ?>"
|
||||
data-api-url="<?php echo $station_apiradio; ?>">
|
||||
<i class="material-icons play-icon" id="play-pause" style="font-size: 35px; border-radius: 10px; border: 2px solid #ffffff; padding: 4px 5px 4px 4px; margin-top: -2px; background: #f7b835; color: #2a377e;">play_arrow</i>
|
||||
<i class="material-icons pause-icon" id="play-pause" style="display:none; font-size: 35px; border-radius: 10px; border: 2px solid #ffffff; padding: 4px 5px 4px 4px; margin-top: -2px; background: #f7b835; color: #2a377e;">pause</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-2" style="text-align: center; margin-top: 1px; margin-right: 5px; width: 67px;">
|
||||
<button id="playPauseBtn" data-stream-hls="<?php echo $station->streamhls; ?>" data-stream-fallback="<?php echo $station->stream; ?>" data-station-name="<?php echo htmlspecialchars($station->name); ?>" data-station-logo="<?php echo $station->logo; ?>" data-station-slogan="<?php echo htmlspecialchars($station->slogan); ?>">
|
||||
<i class="material-icons play-icon" id="play-pause" style="font-size: 35px; border-radius: 10px; border: 2px solid #ffffff; padding: 4px 5px 4px 4px; margin-top: -2px; background: #f7b835; color: #2a377e;">play_arrow</i>
|
||||
<i class="material-icons pause-icon" id="play-pause" style="display:none; font-size: 35px; border-radius: 10px; border: 2px solid #ffffff; padding: 4px 5px 4px 4px; margin-top: -2px; background: #f7b835; color: #2a377e;">pause</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<audio id="hlsAudioPlayer" preload="none"></audio>
|
||||
Binary file not shown.
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
// Assicurati che $station sia definito (dovrebbe essere passato da mobile.php)
|
||||
if (!isset($station) || empty($station)) {
|
||||
echo '<div class="alert alert-danger">Errore: Stazione TV non trovata.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$station_id = (string)$station->id;
|
||||
$station_name = (string)$station->name;
|
||||
$station_logo = (string)$station->logo;
|
||||
$station_stream = (string)$station->stream;
|
||||
$station_poster = isset($station->poster) ? (string)$station->poster : '';
|
||||
?>
|
||||
|
||||
<!-- Container player con sfondo bianco -->
|
||||
<div class="tv-player-container" style="background-color: #ffffff;height: calc(100% - <?php if($is_mobile){ echo "232px"; }else{ echo "217px"; } ?>);position: absolute;left: calc(50%);display: flex;flex-direction: column;max-width: 750px;transform: translateX(-50%);width: 100%;">
|
||||
|
||||
<!-- Header semplice con pulsante indietro e nome -->
|
||||
<div class="tv-header" style="padding: 20px; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/tv" data-page="tv" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;"><?php echo $station_name; ?></span>
|
||||
</div>
|
||||
|
||||
<?php if(!empty($station_logo)): ?>
|
||||
<div class="right-controls">
|
||||
<img src="<?php echo $station_logo; ?>" alt="Logo" style="height: 30px; width: auto;">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Area Video -->
|
||||
<div class="video-wrapper" style="flex: 1; display: flex; align-items: center; justify-content: center; background-color: #000;">
|
||||
<video id="tvVideoPlayer"
|
||||
class="video-js"
|
||||
controls
|
||||
playsinline
|
||||
data-src="<?php echo $station_stream; ?>"
|
||||
poster="<?php echo $station_poster; ?>"
|
||||
style="width: 100%; max-width: 100%; max-height: 100vh; aspect-ratio: 16/9;">
|
||||
<p class="vjs-no-js">
|
||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
||||
<a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
|
||||
</p>
|
||||
</video>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Binary file not shown.
@@ -1,200 +0,0 @@
|
||||
<?php
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
// Feeds configuration
|
||||
$feeds = [
|
||||
['url' => "https://www.radiodiffusionelibera.com/podcast/feed/", 'source' => 'RDL'],
|
||||
['url' => "https://www.radiocitta105.it/podcast/feed/", 'source' => 'Radio Città 105']
|
||||
];
|
||||
|
||||
$all_items = [];
|
||||
foreach ($feeds as $feed) {
|
||||
// Caricamento feed con soppressione errori per non bloccare l'intera lista
|
||||
$rss = @simplexml_load_file($feed['url']);
|
||||
if ($rss && isset($rss->channel->item)) {
|
||||
foreach ($rss->channel->item as $item) {
|
||||
$all_items[] = [
|
||||
'title' => (string)$item->title,
|
||||
'link' => (string)$item->link,
|
||||
'pubDate' => (string)$item->pubDate,
|
||||
'timestamp' => strtotime((string)$item->pubDate),
|
||||
'source' => $feed['source']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ordinamento cronologico decrescente (i più recenti in alto)
|
||||
usort($all_items, function($a, $b) {
|
||||
return $b['timestamp'] - $a['timestamp'];
|
||||
});
|
||||
|
||||
function formatDateItalian($dateString) {
|
||||
try {
|
||||
$date = new DateTime($dateString);
|
||||
$months = [
|
||||
'January' => 'Gennaio', 'February' => 'Febbraio', 'March' => 'Marzo',
|
||||
'April' => 'Aprile', 'May' => 'Maggio', 'June' => 'Giugno',
|
||||
'July' => 'Luglio', 'August' => 'Agosto', 'September' => 'Settembre',
|
||||
'October' => 'Ottobre', 'November' => 'Novembre', 'December' => 'Dicembre'
|
||||
];
|
||||
$formatted = $date->format('j F Y');
|
||||
return strtr($formatted, $months);
|
||||
} catch (Exception $e) {
|
||||
return $dateString;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<style>
|
||||
.podcast-container {
|
||||
position: relative;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.podcast-item {
|
||||
background: #ffffff;
|
||||
border-left: 5px solid #2a377e;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 15px;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.podcast-item:hover {
|
||||
/*transform: translateY(-4px);*/
|
||||
/*box-shadow: 0 12px 20px rgba(42, 55, 126, 0.15);*/
|
||||
background: #f8faff;
|
||||
}
|
||||
.podcast-source {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 50px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.source-rdl {
|
||||
background: #eef1ff;
|
||||
color: #2a377e;
|
||||
border: 1px solid #2a377e30;
|
||||
}
|
||||
.source-rc105 {
|
||||
background: #fff4e5;
|
||||
color: #e65100;
|
||||
border: 1px solid #e6510030;
|
||||
}
|
||||
.podcast-title {
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.podcast-date {
|
||||
font-size: 0.8rem;
|
||||
color: #777;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.podcast-date .material-icons {
|
||||
font-size: 14px;
|
||||
margin-right: 6px;
|
||||
color: #f7b835;
|
||||
}
|
||||
#podcast-detail {
|
||||
display: none;
|
||||
animation: slideIn 0s ease-out;
|
||||
position: fixed;background: #ffffff;top: 148px;left: 0;width: 100%;
|
||||
}
|
||||
@keyframes slideIn {
|
||||
from { opacity: 0; transform: translateX(0); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
.podcast-header-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 0 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.podcast-iframe {
|
||||
width: 100%;
|
||||
height: calc(100vh - 173px);
|
||||
border: none;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
background: #f9f9f9;
|
||||
margin-top: -54px;
|
||||
}
|
||||
.error-msg {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: #666;
|
||||
}
|
||||
.error-msg i {
|
||||
font-size: 48px;
|
||||
color: #ccc;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="radio-header" id="podcast-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;z-index: 1;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Podcast</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tec px-4">
|
||||
<div id="podcast-container" class="podcast-container">
|
||||
|
||||
<!-- Podcast List -->
|
||||
<div id="podcast-list">
|
||||
<?php if (!empty($all_items)): ?>
|
||||
<?php foreach ($all_items as $item): ?>
|
||||
<div class="podcast-item" onclick="openPodcast('<?php echo addslashes($item['link']); ?>', '<?php echo addslashes($item['title']); ?>')">
|
||||
<div class="podcast-source <?php echo $item['source'] === 'RDL' ? 'source-rdl' : 'source-rc105'; ?>">
|
||||
<?php echo $item['source']; ?>
|
||||
</div>
|
||||
<div class="podcast-title"><?php echo $item['title']; ?></div>
|
||||
<div class="podcast-date">
|
||||
<span class="material-icons">calendar_today</span>
|
||||
<?php echo formatDateItalian($item['pubDate']); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<div class="error-msg">
|
||||
<span class="material-icons">rss_feed</span>
|
||||
<p>Impossibile caricare i podcast al momento. Riprova più tardi.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Podcast Detail (Iframe) -->
|
||||
<div id="podcast-detail">
|
||||
<div class="radio-header" style="padding: 20px; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: relative;background: white; z-index: 5;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<div class="back-to-list" onclick="closePodcast()" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none; cursor: pointer;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</div>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Torna ai podcast</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<iframe id="podcast-iframe" class="podcast-iframe" src="about:blank"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white; z-index: 1;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Policy Privacy</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="titlePage">Policy Privacy</h1>
|
||||
<p class="subtitlePage">Ultimo aggiornamento: 17/11/2025</p>
|
||||
|
||||
<div class="tec px-4">
|
||||
<p>Ultimo aggiornamento: 17/11/2025</p>
|
||||
<hr>
|
||||
<hr>
|
||||
<div class="tec">
|
||||
<p><b>Titolare del Trattamento</b><br>Il Titolare del trattamento dei dati personali è A.S.V. Studios APPS, con sede legale in Italia, contattabile all’indirizzo e-mail <a href="mailto:pp.app@rpigroup.net">pp.app@rpigroup.net</a>. Per ulteriori informazioni o per esercitare i diritti previsti dalla normativa sulla protezione dei dati personali, è possibile inviare una richiesta scritta all’indirizzo sopra indicato.</p>
|
||||
<p>
|
||||
<b>Dati Raccolti</b><br>
|
||||
@@ -57,4 +50,11 @@
|
||||
Si prega di indicare nell’oggetto dell’e-mail il diritto che si intende esercitare e di fornire i propri dati identificativi per facilitare la gestione della richiesta.
|
||||
</p>
|
||||
<p><b>Modifiche a questa Informativa</b><br>La presente informativa può essere soggetta a modifiche e aggiornamenti. La versione più recente sarà sempre disponibile all’interno del Servizio. Gli utenti saranno informati delle modifiche rilevanti tramite una notifica all’interno del Servizio, così da garantire massima trasparenza e permettere a tutti di essere sempre aggiornati.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+13
-10
@@ -5,16 +5,12 @@
|
||||
$stations = loadRadioStations();
|
||||
?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Radio</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="titlePage">Radio</h1>
|
||||
<p class="subtitlePage">Seleziona la tua radio che vuoi ascoltare</p>
|
||||
|
||||
<div class="stationList px-4">
|
||||
<hr>
|
||||
|
||||
<div class="stationList">
|
||||
<div class="row g-2">
|
||||
<?php foreach ($stations as $station): ?>
|
||||
<div class="col-6">
|
||||
@@ -26,4 +22,11 @@ $stations = loadRadioStations();
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
@@ -1,17 +1,11 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white; z-index: 1;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">Termini e Condizioni</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="titlePage">Termini & Condizioni</h1>
|
||||
<p class="subtitlePage">Ultimo aggiornamento: 17/11/2025</p>
|
||||
|
||||
<div class="tec px-4">
|
||||
<p>Ultimo aggiornamento: 17/11/2025</p>
|
||||
<hr>
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<p><b>Introduzione</b><br> RPIGroup Play vi dà il benvenuto. I presenti Termini e Condizioni (di seguito “T&C”) regolamentano l’accesso e l’uso dell’applicazione “RPIGroup Play” (di seguito “Portale”, “Servizio”, “Applicazione” e “Sito”) e tutti i servizi correlati. Accedendo e utilizzando il Portale, l’utente (di seguito “Utente”) accetta i presenti T&C al primo accesso, condizione necessaria per poter utilizzare il Servizio. L’utente potrà in qualsiasi momento declinare i seguenti T&C, sapendo che non potrà più accedere all’Applicazione offerta.</p>
|
||||
<p><b>Titolarità e Gestione</b><br>RPIGroup Play è fornito da A.S.V. Studios APPS (di seguito “Gestore”, anche indicato come “Proprietario” e “Sviluppatore”), unico titolare del presente Servizio.</p>
|
||||
<p><b>Descrizione del Servizio</b><br>L’Applicazione consente di ascoltare in streaming le emittenti iscritte all'interno del gruppo RPIGroup, sia in formato audio e video (ove previsto).</p>
|
||||
@@ -34,4 +28,11 @@
|
||||
<!-- <p><b>Criteri per l’Interruzione e la Cessazione</b><br>Il Gestore può, a sua esclusiva discrezione, sospendere o chiudere l’account dell’Utente in caso di violazione dei presenti T&C. Tali violazioni includono, a titolo esemplificativo ma non esaustivo, comportamenti fraudolenti, uso improprio della piattaforma o mancato rispetto delle regole di condotta. Prima che venga presa una decisione definitiva sulla sospensione o chiusura dell’account, l’Utente avrà la possibilità di presentare le proprie osservazioni o contestare la decisione.</p> -->
|
||||
<p><b>Leggi Applicabile e Foro di Competente</b><br>Questi Termini e Condizioni sono regolati dalla legge italiana. In caso di controversie riguardanti l’interpretazione o l’applicazione dei Termini e Condizioni, la competenza sarà attribuita esclusivamente al Tribunale di Milano, salvo diversa indicazione prevista dalla legge per l’Utente, come nei casi in cui la normativa vigente, ad esempio il Codice del Consumo, preveda il foro di residenza o domicilio del consumatore.</p>
|
||||
<p><b>Accettazione dei Termini e Condizioni</b><br>L'Utente accetta automaticamente i seguenti termini e condizioni tramite l'accesso all'interno dell'Applicazione.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
+11
-23
@@ -1,29 +1,17 @@
|
||||
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
|
||||
|
||||
<?php
|
||||
// views/home.php - Vista della pagina principale
|
||||
$stations = loadTvStations();
|
||||
?>
|
||||
<h1 class="titlePage">TV</h1>
|
||||
<p class="subtitlePage">Guarda in streaming <b>RC105 TV</b></p>
|
||||
|
||||
<div class="radio-header" style="padding: 20px; margin: 0 0 20px 0; border-bottom: 1px solid #eee; display: flex; align-items: center; justify-content: space-between;position: sticky;top: 0px;background: white;">
|
||||
<div class="left-controls" style="display: flex; align-items: center;">
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox" style="color: #333; display: flex; align-items: center; text-decoration: none;">
|
||||
<span class="material-icons" style="font-size: 28px;">arrow_back</span>
|
||||
</a>
|
||||
<span style="font-size: 18px; font-weight: 600; color: #333; margin-left: 15px;">TV</span>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="tec">
|
||||
<iframe src="https://tv.rpigroup.net/a9699134-efb3-4932-b8db-5a49ae214031.html" style="width:100%; height: 225px;" frameborder="no" scrolling="no" allowfullscreen="true"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="stationList px-4">
|
||||
<div class="row g-2">
|
||||
<?php foreach ($stations as $station): ?>
|
||||
<div class="col-6">
|
||||
<div class="stationCard <?php if((string)$station->thematic === 'true'){echo "isthematic";} ?>" data-id="<?php echo $station->id; ?>">
|
||||
<a href="<?php echo $base_path; ?>/playtv/<?php echo $station->id; ?>" data-page="playtv/<?php echo $station->id; ?>" class="nav-link stationLink">
|
||||
<img src="<?php echo $station->logo; ?>" alt="<?php echo $station->name; ?>" class="stationLogo">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<a href="<?php echo $base_path; ?>/home" data-page="home" class="linkBox mt-3">
|
||||
<div class="clickBox mt-5 mb-4">
|
||||
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/></svg>
|
||||
Torna alla Home
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
// File: process_contact.php
|
||||
|
||||
// Imposta header per JSON
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Verifica se il modulo è stato inviato
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
// Raccolta e pulizia dei dati
|
||||
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
|
||||
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
|
||||
$subject = filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_STRING);
|
||||
$message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING);
|
||||
|
||||
// Validazione dei dati
|
||||
$errors = [];
|
||||
|
||||
if (empty($name)) {
|
||||
$errors[] = "Il nome è richiesto";
|
||||
}
|
||||
|
||||
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = "Email non valida";
|
||||
}
|
||||
|
||||
if (empty($subject)) {
|
||||
$errors[] = "L'oggetto è richiesto";
|
||||
}
|
||||
|
||||
if (empty($message)) {
|
||||
$errors[] = "Il messaggio è richiesto";
|
||||
}
|
||||
|
||||
// Se non ci sono errori, procedi con l'invio della mail
|
||||
if (empty($errors)) {
|
||||
// Destinatario
|
||||
$to = "info@tuoaggregatore.it";
|
||||
|
||||
// Intestazioni
|
||||
$headers = "From: $name <$email>" . "\r\n";
|
||||
$headers .= "Reply-To: $email" . "\r\n";
|
||||
$headers .= "X-Mailer: PHP/" . phpversion();
|
||||
|
||||
// Prova a inviare l'email
|
||||
$success = mail($to, $subject, $message, $headers);
|
||||
|
||||
if ($success) {
|
||||
echo json_encode(['success' => true, 'message' => 'Messaggio inviato con successo']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Impossibile inviare il messaggio']);
|
||||
}
|
||||
} else {
|
||||
// Restituisci errori di validazione
|
||||
echo json_encode(['success' => false, 'message' => implode(', ', $errors)]);
|
||||
}
|
||||
} else {
|
||||
// Se qualcuno prova ad accedere direttamente a questa pagina
|
||||
echo json_encode(['success' => false, 'message' => 'Metodo non consentito']);
|
||||
}
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user