Compare commits
44 Commits
feature/ap
...
c7243f31a0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7243f31a0 | ||
|
|
2e1f496eea | ||
|
|
37745e8ae9 | ||
|
|
eb9813c239 | ||
|
|
9dc9b30afa | ||
|
|
761cec4257 | ||
|
|
0e2148956f | ||
| 1863ff766f | |||
| 96748c0c01 | |||
| c16a2db01d | |||
| df4d48a327 | |||
| 187fc7b273 | |||
| 06e7741d3b | |||
| 262aec618b | |||
| 98a9cd2c53 | |||
| 21ca729958 | |||
| 367527098d | |||
| a86f8e56a1 | |||
| c1ddaa15c6 | |||
| 39f1ee4823 | |||
| 71a5d3a690 | |||
|
|
6db6de8e49 | ||
|
|
e06ce1507b | ||
| 3ef630c7cc | |||
| 2ba81f8550 | |||
| f3fa2c109a | |||
| 52df85716b | |||
| 22292e10ed | |||
| 9428e1d2ee | |||
| 1c587684f3 | |||
| 918255be1c | |||
|
|
35a5aa636f | ||
|
|
e2551b1dab | ||
|
|
552c638571 | ||
|
|
a930fb7216 | ||
|
|
58ea5c0c85 | ||
|
|
8616cb3d56 | ||
|
|
dbca7e2bc5 | ||
|
|
437e6243e7 | ||
|
|
6008d3175b | ||
|
|
ab7246e123 | ||
|
|
d9627a54c4 | ||
|
|
6c732f90e8 | ||
|
|
1dadbc62af |
@@ -10,7 +10,7 @@ class CalendarController extends Controller
|
||||
{
|
||||
parent::registerView($request, 'agenda', $id);
|
||||
$apiResult = $this->API('agenda/item/' . (int)$id);
|
||||
$calendarEvent = new \Model\CalendarEvent($apiResult);
|
||||
$calendarEvent = new \Model\CalendarEvent($apiResult->news);
|
||||
|
||||
return view('calendarevent', array_merge($this->getSidebareData(), ['event' => $calendarEvent, 'metadata' => $calendarEvent->metadata]));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class Controller extends BaseController
|
||||
$this->getDataFromFileAndConvert('laatste_podcasts.json', ['podcasts'], '\Model\Podcast'));
|
||||
});
|
||||
|
||||
View::share('disableBanners', env('DISABLE_BANNERS', true));
|
||||
View::share('disableBanners', env('DISABLE_BANNERS', false));
|
||||
}
|
||||
|
||||
protected function registerView(Request $request, $type, $id)
|
||||
|
||||
@@ -22,22 +22,24 @@ class NewsController extends Controller
|
||||
|
||||
switch ($apiResult->version) {
|
||||
case 1:
|
||||
if (!$newsItem->content) return redirect('//nhnieuws.nl/gooi');
|
||||
return view('newsitem', ['news' => $newsItem, 'metadata' => $newsItem->metadata]);
|
||||
break;
|
||||
if (!$newsItem->content) return redirect('//nhnieuws.nl/gooi');
|
||||
|
||||
case 2:
|
||||
case 2:
|
||||
if(isset($apiResult->source->article)) {
|
||||
$source = $apiResult->source->article;
|
||||
$newsItem->published = self::TimestampToDateTime($source->created);
|
||||
$newsItem->edited = self::TimestampToDateTime($source->updated);
|
||||
$newsItem->author = $source->author;
|
||||
$newsItem->images = null; // Images will be embedded
|
||||
$newsItem->video = null; // Videos will be embedded
|
||||
$newsItem->content = $source->blocks;
|
||||
$newsItem->content = $source->blocks;
|
||||
} elseif(isset($apiResult->source->blocks)) {
|
||||
$newsItem->content = $apiResult->source->blocks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return view('newsitem', array_merge($this->getSidebareData(), ['news' => $newsItem, 'metadata' => $newsItem->metadata, 'searchURL' => 'nieuws/zoeken']));
|
||||
return view('newsitem', array_merge($this->getSidebareData(), ['type' => $apiResult->type, 'news' => $newsItem, 'metadata' => $newsItem->metadata, 'searchURL' => 'nieuws/zoeken']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,11 +188,15 @@ class NewsController extends Controller
|
||||
|
||||
public function regionieuws()
|
||||
{
|
||||
$data = $this->API('nieuws/regionieuws.json');
|
||||
return view('listen', [
|
||||
'source' => $this->API_URL . 'nieuws/regionieuws',
|
||||
'source' => $this->API_URL . 'nieuws/regionieuws.mp3',
|
||||
'title' => 'Regionieuws',
|
||||
'content' => 'het laatste nieuws uit de regio',
|
||||
'isStream' => false,
|
||||
'canDownload' => true]);
|
||||
'canDownload' => true,
|
||||
'lengte' => $data->length * 0.25,
|
||||
'waveform' => $data
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ class RadioController extends Controller
|
||||
{
|
||||
$programs = [];
|
||||
$now = new \DateTimeImmutable('2 minutes ago');
|
||||
$page = (int)$request->get('pagina', 1);
|
||||
$page = (int)$request->get('pagina', 1);
|
||||
$apiResult = $this->API('programma/schema/recent?pagina=' . (int)max(1, $page) . '&aantal=12');
|
||||
foreach($apiResult->schedule as $item) {
|
||||
if(!$item->program->nonstop && !$item->program->rerun) {
|
||||
|
||||
@@ -14,6 +14,8 @@ class StreamController extends Controller
|
||||
return view('listen', [
|
||||
'source' => self::$STREAM_URL . 'mp3live',
|
||||
'title' => 'Luister live',
|
||||
'lengte' => 0,
|
||||
'waveform' => null,
|
||||
'content' => 'de live-uitzending van NH Gooi.',
|
||||
'isStream' => true ]);
|
||||
}
|
||||
@@ -53,13 +55,20 @@ class StreamController extends Controller
|
||||
'source' => $this->API_URL . 'podcast/stream/' . $apiResult->url,
|
||||
'title' => $podcast->title,
|
||||
'content' => $podcast->title,
|
||||
'lengte' => $podcast->duration / 1000,
|
||||
'waveform' => $podcast->waveform,
|
||||
'isStream' => false,
|
||||
'canDownload' => $this->API_URL . 'podcast/download/' . $apiResult->url ]);
|
||||
}
|
||||
|
||||
public function program(Request $request, $year, $month, $day, $hour, $duration, $offset = 0) {
|
||||
$date = (new \DateTimeImmutable())->setDate($year, $month, $day)->setTime($hour, 0, 0);
|
||||
$current = $date->add(\DateInterval::createFromDateString($offset . ' hours'));
|
||||
$current = $date->add(\DateInterval::createFromDateString($offset . ' hours'));
|
||||
|
||||
$programma = $this->API("programma/details/" . $current->Format("Y/m/d/H"));
|
||||
if(!$programma->is_beschikbaar) {
|
||||
return view('listen', ['notAvailable' => true]);
|
||||
}
|
||||
|
||||
$hours = [];
|
||||
for($i = 0; $i < $duration; $i++) {
|
||||
@@ -72,7 +81,9 @@ class StreamController extends Controller
|
||||
'source' => $this->API_URL . 'programma/stream/' . $current->format('Y/m/d/H'),
|
||||
'tabs' => $hours,
|
||||
'title' => 'Uitzending terugluisteren',
|
||||
'content' => 'de uitzending van ' . $current->format('d-m-Y, H') . ':00 uur',
|
||||
'lengte' => $programma->waveform->length,
|
||||
'waveform' => $programma->waveform,
|
||||
'content' => $programma->programma->name . ' van ' . $current->format('d-m-Y, H') . ':00 uur',
|
||||
'isStream' => false,
|
||||
'canDownload' => false ]);
|
||||
}
|
||||
|
||||
203
public/css/style.css
vendored
203
public/css/style.css
vendored
@@ -162,6 +162,16 @@ div.pp_default .pp_close:hover {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.ad-prefix {
|
||||
width: 100%;
|
||||
font-family: Nunito, serif;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 3.17;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 111px;
|
||||
}
|
||||
@@ -172,10 +182,11 @@ div.pp_default .pp_close:hover {
|
||||
.header .logo img {
|
||||
height: 95px;
|
||||
}
|
||||
.header .advertisement {
|
||||
.header ins[data-revive-zoneid] {
|
||||
float: right;
|
||||
width: 728px;
|
||||
height: 90px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 1170px) {
|
||||
@@ -190,7 +201,7 @@ div.pp_default .pp_close:hover {
|
||||
.header .logo {
|
||||
float: none;
|
||||
}
|
||||
.header .advertisement {
|
||||
.header ins[data-revive-zoneid] {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
@@ -778,6 +789,11 @@ div.pp_default .pp_close:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.article-iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.box_header {
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding-right: 20px;
|
||||
@@ -1151,6 +1167,16 @@ div.pp_default .pp_close:hover {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
ins[data-revive-zoneid] img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.homepage-body-banners {
|
||||
margin-top: -4rem;
|
||||
}
|
||||
|
||||
.news .blog .post {
|
||||
height: 115px;
|
||||
}
|
||||
@@ -1204,6 +1230,19 @@ div.pp_default .pp_close:hover {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.box.featured .sentence, .post_container .post_body .sentence {
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
line-height: 1.3;
|
||||
text-align: right;
|
||||
color: #585858;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.box.featured .sentence span, .post_container .post_body .sentence span {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.post_container {
|
||||
max-width: 1170px;
|
||||
margin: 0 auto;
|
||||
@@ -1231,20 +1270,6 @@ div.pp_default .pp_close:hover {
|
||||
.post_container .post_body h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
.post_container .post_body .sentence,
|
||||
.box.featured .sentence {
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
line-height: 1.3;
|
||||
text-align: right;
|
||||
color: #585858;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.post_container .post_body .sentence span,
|
||||
.box.featured .sentence span {
|
||||
padding: 0 5px;
|
||||
}
|
||||
.post_container .post_body blockquote {
|
||||
border-left: 3px solid #5ba8f4;
|
||||
margin-left: 0;
|
||||
@@ -1262,6 +1287,9 @@ div.pp_default .pp_close:hover {
|
||||
line-height: 3.17;
|
||||
color: #585858;
|
||||
}
|
||||
.post_container .post_body div.text {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.post_container .post_body .post_details {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -1309,19 +1337,7 @@ div.pp_default .pp_close:hover {
|
||||
color: #ED1C24;
|
||||
}
|
||||
|
||||
.post_tags {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
height: 31px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.post_tags li {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.post_tags li a,
|
||||
#schedule .onair {
|
||||
#schedule .onair, .post_tags li a {
|
||||
display: block;
|
||||
width: 4rem;
|
||||
padding: 6px 15px 7px;
|
||||
@@ -1336,18 +1352,36 @@ div.pp_default .pp_close:hover {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#schedule a {
|
||||
text-decoration: none;
|
||||
.post_tags {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
height: 31px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.post_tags li {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
@keyframes tilt-shaking {
|
||||
0% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(5deg); }
|
||||
50% { transform: rotate(0deg); }
|
||||
75% { transform: rotate(-5deg); }
|
||||
100% { transform: rotate(0deg); }
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
.onair {
|
||||
animation: tilt-shaking 1s linear infinite;
|
||||
#schedule a {
|
||||
text-decoration: none;
|
||||
}
|
||||
#schedule .program-title {
|
||||
font-family: Montserrat, serif;
|
||||
@@ -1387,6 +1421,9 @@ div.pp_default .pp_close:hover {
|
||||
#schedule .no-results span, #schedule .loading span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
#schedule .onair {
|
||||
animation: tilt-shaking 1s linear infinite;
|
||||
}
|
||||
|
||||
.page_container {
|
||||
max-width: 1170px;
|
||||
@@ -1476,6 +1513,90 @@ div.pp_default .pp_close:hover {
|
||||
margin: 10px 20px 0 0;
|
||||
}
|
||||
|
||||
.podcast-player .content {
|
||||
border: solid 1px #333;
|
||||
border-radius: 5px;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.audioplayer .waveform {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.audioplayer .hover {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
mix-blend-mode: overlay;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
.audioplayer .waveform:hover .hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.audioplayer .time,
|
||||
.audioplayer .duration {
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
top: 50%;
|
||||
margin-top: -1px;
|
||||
transform: translateY(-50%);
|
||||
font-size: 11px;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
padding: 2px;
|
||||
color: #ddd;
|
||||
}
|
||||
.audioplayer .time {
|
||||
left: 0;
|
||||
}
|
||||
.audioplayer .duration {
|
||||
right: 0;
|
||||
}
|
||||
.audioplayer .audio-controls {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
.audioplayer .audio-controls .btn {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-transform: none;
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.audioplayer .audio-controls .btn label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.audioplayer .audio-controls .btn.btn-play {
|
||||
flex: 50% 1 0;
|
||||
}
|
||||
.audioplayer .volume-controls {
|
||||
display: flex;
|
||||
}
|
||||
.audioplayer .volume-controls .volume-slider {
|
||||
flex: 100% 1 1;
|
||||
}
|
||||
.audioplayer .audio-controls .btn,
|
||||
.audioplayer .volume-controls .btn-toggle-mute {
|
||||
flex: 100px 1 1;
|
||||
padding: 10px 0 10px 0;
|
||||
background: #5ba8f4;
|
||||
border-radius: 5px;
|
||||
border-color: solid 1px #0f259d;
|
||||
color: white;
|
||||
font-family: Nunito, serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer_container {
|
||||
font-family: Montserrat, serif;
|
||||
font-size: 14px;
|
||||
@@ -1663,10 +1784,4 @@ a, a:hover, a:active {
|
||||
}
|
||||
}
|
||||
|
||||
.podcast-player .content {
|
||||
border: solid 1px #333;
|
||||
border-radius: 5px;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
public/js/wavesurfer.min.js
vendored
Normal file
1
public/js/wavesurfer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
resources/assets/sass/base/_base.scss
vendored
1
resources/assets/sass/base/_base.scss
vendored
@@ -5,6 +5,7 @@
|
||||
@use "../components/pretty_photo";
|
||||
@use "../components/cookie";
|
||||
@use "../components/list";
|
||||
@use "../components/banners";
|
||||
|
||||
@use "../layout";
|
||||
|
||||
|
||||
9
resources/assets/sass/components/_banners.scss
vendored
Normal file
9
resources/assets/sass/components/_banners.scss
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.ad-prefix {
|
||||
width: 100%;
|
||||
font-family: Nunito, serif;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 3.17;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
}
|
||||
@@ -7,10 +7,11 @@
|
||||
height: 95px;
|
||||
}
|
||||
}
|
||||
.advertisement {
|
||||
ins[data-revive-zoneid] {
|
||||
float: right;
|
||||
width: 728px;
|
||||
height: 90px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +26,7 @@
|
||||
.logo {
|
||||
float: none;
|
||||
}
|
||||
.advertisement {
|
||||
ins[data-revive-zoneid] {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
|
||||
.post_details {
|
||||
@include reset-list;
|
||||
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
.category a {
|
||||
padding: 6px 11px 7px;
|
||||
border-radius: 3px;
|
||||
@@ -105,3 +106,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.article-iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
91
resources/assets/sass/components/_media.scss
vendored
Normal file
91
resources/assets/sass/components/_media.scss
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
.audioplayer {
|
||||
.waveform {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hover {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
mix-blend-mode: overlay;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.waveform:hover .hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.time,
|
||||
.duration {
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
top: 50%;
|
||||
margin-top: -1px;
|
||||
transform: translateY(-50%);
|
||||
font-size: 11px;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
padding: 2px;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.time {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.duration {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.audio-controls {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.audio-controls .btn {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
@media(max-width: 720px) {
|
||||
.audio-controls .btn label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.audio-controls .btn.btn-play {
|
||||
flex: 50% 1 0;
|
||||
}
|
||||
|
||||
.volume-controls {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.volume-controls .volume-slider {
|
||||
flex: 100% 1 1;
|
||||
}
|
||||
|
||||
.audio-controls .btn,
|
||||
.volume-controls .btn-toggle-mute {
|
||||
flex: 100px 1 1;
|
||||
padding: 10px 0 10px 0;
|
||||
background: #5ba8f4;
|
||||
border-radius: 5px;
|
||||
border-color: solid 1px #0f259d;
|
||||
color: white;
|
||||
font-family: Nunito, serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
2
resources/assets/sass/components/_menu.scss
vendored
2
resources/assets/sass/components/_menu.scss
vendored
@@ -124,7 +124,7 @@
|
||||
margin: 8px auto;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
&.search {
|
||||
border: none;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -12,3 +12,9 @@
|
||||
float: left;
|
||||
margin: 10px 20px 0 0;
|
||||
}
|
||||
|
||||
.podcast-player .content {
|
||||
border: solid 1px #333;
|
||||
border-radius: 5px;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
64
resources/assets/sass/components/_post.scss
vendored
64
resources/assets/sass/components/_post.scss
vendored
@@ -1,6 +1,20 @@
|
||||
@use "../abstracts/mixin" as *;
|
||||
@use "../abstracts/variables" as *;
|
||||
|
||||
%sentence {
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
line-height: 1.3;
|
||||
text-align: right;
|
||||
color: $text-description-color;
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.post_container {
|
||||
@include container;
|
||||
@media (min-width: 768px) {
|
||||
@@ -30,17 +44,15 @@
|
||||
}
|
||||
|
||||
.sentence {
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
line-height: 1.3;
|
||||
text-align: right;
|
||||
color: $text-description-color;
|
||||
display: block;
|
||||
width: 100%;
|
||||
@extend %sentence
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 0 5px;
|
||||
}
|
||||
@at-root .box.featured .sentence {
|
||||
@extend %sentence
|
||||
}
|
||||
|
||||
div.text {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
@@ -106,6 +118,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%post-tags-link {
|
||||
display: block;
|
||||
width: 4rem;
|
||||
padding: 6px 15px 7px;
|
||||
border-radius: 3px;
|
||||
background-image: linear-gradient(to left, #0d1ca3, #45aaf8);
|
||||
font-family: Nunito, serif;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: $text-inverted-color;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.post_tags {
|
||||
@include reset-list;
|
||||
height: 31px;
|
||||
@@ -116,17 +144,11 @@
|
||||
margin-right: 10px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 6px 15px 7px;
|
||||
border-radius: 3px;
|
||||
background-image: linear-gradient(to left, #0d1ca3, #45aaf8);
|
||||
font-family: Nunito, serif;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: $text-inverted-color;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
@extend %post-tags-link
|
||||
}
|
||||
|
||||
@at-root #schedule .onair {
|
||||
@extend %post-tags-link
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
resources/assets/sass/components/_schedule.scss
vendored
12
resources/assets/sass/components/_schedule.scss
vendored
@@ -1,6 +1,14 @@
|
||||
@use "../abstracts/mixin" as *;
|
||||
@use "../abstracts/variables" as *;
|
||||
|
||||
@keyframes tilt-shaking {
|
||||
0% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(5deg); }
|
||||
50% { transform: rotate(0deg); }
|
||||
75% { transform: rotate(-5deg); }
|
||||
100% { transform: rotate(0deg); }
|
||||
}
|
||||
|
||||
#schedule {
|
||||
a {
|
||||
text-decoration: none;
|
||||
@@ -32,4 +40,8 @@
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.onair {
|
||||
animation: tilt-shaking 1s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
11
resources/assets/sass/layout/_home.scss
vendored
11
resources/assets/sass/layout/_home.scss
vendored
@@ -6,3 +6,14 @@
|
||||
@use "../components/contact_box";
|
||||
@use "../components/featured";
|
||||
@use "../components/podcast_items";
|
||||
|
||||
@media (max-width: 576px) {
|
||||
ins[data-revive-zoneid] img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.homepage-body-banners {
|
||||
margin-top: -4rem;
|
||||
}
|
||||
|
||||
1
resources/assets/sass/layout/_podcast.scss
vendored
1
resources/assets/sass/layout/_podcast.scss
vendored
@@ -1 +1,2 @@
|
||||
@use "../components/podcast_item";
|
||||
@use "../components/media";
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
@include('partial/nh_story', ['content' => $event->content]);
|
||||
@else
|
||||
<div class="text">
|
||||
<p>{!!$event->content!!}</p>
|
||||
{!!$event->content!!}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
@php($count = 0)
|
||||
@foreach($events as $event)
|
||||
@php($count++)
|
||||
<?php $url = route('agenda.details', ['id' => $event->id, 'title' => $event->title]); ?>
|
||||
<?php $url = $event->url; ?>
|
||||
<div class="box featured">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6">
|
||||
@@ -52,15 +52,19 @@
|
||||
<div class="col-12 col-md-6">
|
||||
<h2 class="post_title"><a href="{{$url}}" title="{{$event->title}}">{!!$event->title!!}</a></h2>
|
||||
<div class="sub_title" style="flex-wrap: wrap">
|
||||
<ul class="post_tags" style="width: 100%; margin: 0 0 8px 0;height: 25px;">
|
||||
@foreach($event->tags as $tag)
|
||||
<li><a style="padding: 3px 8px 3px" title="{{$tag->title}}">{{$tag->title}}</a></li>
|
||||
<ul class="post_tags" style="width: 100%; margin: 0 0 8px 0;height: 25px;">
|
||||
@foreach($event->tags as $tag)
|
||||
<li><a style="padding: 3px 8px 3px" title="{{$tag->title}}">{{$tag->title}}</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<span class="post_date" style="line-height: 1.17; height: 14px;" title="{{Formatter::relativeDate($event->starts, 'W d m y?')}}">
|
||||
<i class="fa-regular fa-clock"></i> {{Formatter::relativeDate($event->starts, 'W d m y?')}}
|
||||
@if($event->ends && $event->starts != $event->ends)
|
||||
t/m {{strtolower(Formatter::relativeDate($event->ends, 'W d m y?'))}}
|
||||
@if($event->ends->format('d M y') != $event->starts->format('d M y'))
|
||||
t/m {{strtolower(Formatter::relativeDate($event->ends, 'W d m y?'))}}
|
||||
@else
|
||||
van {{ $event->starts->format('H:i') }} uur tot {{ $event->ends->format('H:i') }} uur
|
||||
@endif
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -61,16 +61,9 @@ voor talent.</p>
|
||||
KvK: 41194132<br>
|
||||
<br>
|
||||
|
||||
<b>Streekredactie</b><br>
|
||||
Gooise Brink, Kerkstraat 63/27<br>
|
||||
11211 CL Hilversum<br>
|
||||
Tiplijn: <a href="tel:+31642913637">06 - 42 91 36 37</a><br>
|
||||
e-mail: {{Html::mailto('info@NHGooi.nl')}}<br>
|
||||
<br>
|
||||
|
||||
<b>Chef redactie</b><br>
|
||||
Petra de Beij<br>
|
||||
{{Html::mailto('petra.debeij@nhgooi.nl')}}<br><br>
|
||||
Erwin Bakker<br>
|
||||
{{Html::mailto('erwin.bakker@nhgooi.nl')}}<br><br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48,19 +48,19 @@
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if($item = next($news))
|
||||
<div class="post large d-block d-md-none">
|
||||
<a href="{{url($item->url)}}" title="{{$item->title}}">
|
||||
@if($item->video)
|
||||
<span class="icon video"></span>
|
||||
@elseif($item->images && count($item->images) > 1)
|
||||
<span class="icon gallery"></span>
|
||||
@endif
|
||||
<img src='{{$item->images && count($item->images) ? $imgBase . $item->images[0]->url : '/images/noimage.png'}}'
|
||||
alt='img'>
|
||||
</a>
|
||||
<div class="slider_content_box">
|
||||
<ul class="post_details simple">
|
||||
@if($item = next($news))
|
||||
<div class="post large d-block d-md-none">
|
||||
<a href="{{url($item->url)}}" title="{{$item->title}}">
|
||||
@if($item->video)
|
||||
<span class="icon video"></span>
|
||||
@elseif($item->images && count($item->images) > 1)
|
||||
<span class="icon gallery"></span>
|
||||
@endif
|
||||
<img src='{{$item->images && count($item->images) ? $imgBase . $item->images[0]->url : '/images/noimage.png'}}'
|
||||
alt='img'>
|
||||
</a>
|
||||
<div class="slider_content_box">
|
||||
<ul class="post_details simple">
|
||||
@foreach($item->tags as $tag)
|
||||
<li class="category">
|
||||
<a title="{{$tag->titel}}"
|
||||
@@ -68,23 +68,23 @@
|
||||
class="over_image">{{$tag->titel}}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<h2><a href="{{url($item->url)}}"
|
||||
title="{{$item->title}}">{!!$item->title!!}</a></h2>
|
||||
<?php
|
||||
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
|
||||
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
|
||||
$time .= ' | bijgewerkt: '
|
||||
. ($item->edited->format('d m') != $item->published->format('d m') ? strtolower(Formatter::relativeDate($item->edited)) : '')
|
||||
. ' ' . $item->edited->format('H:i') . ' uur';
|
||||
}
|
||||
?>
|
||||
<span class="post_date" title="{{$time}}">
|
||||
</ul>
|
||||
<h2><a href="{{url($item->url)}}"
|
||||
title="{{$item->title}}">{!!$item->title!!}</a></h2>
|
||||
<?php
|
||||
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
|
||||
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
|
||||
$time .= ' | bijgewerkt: '
|
||||
. ($item->edited->format('d m') != $item->published->format('d m') ? strtolower(Formatter::relativeDate($item->edited)) : '')
|
||||
. ' ' . $item->edited->format('H:i') . ' uur';
|
||||
}
|
||||
?>
|
||||
<span class="post_date" title="{{$time}}">
|
||||
<i class="fa-regular fa-clock"></i> {{$time}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-8 col-md-6">
|
||||
<div class="row">
|
||||
@@ -102,16 +102,16 @@
|
||||
</a>
|
||||
<div class="slider_content_box">
|
||||
<ul class="post_details simple">
|
||||
@foreach($item->tags as $tag)
|
||||
<li class="category">
|
||||
<a title="{{$tag->titel}}"
|
||||
href="{{route('nieuws.tag', ['tag' => $tag->slug])}}"
|
||||
class="over_image">{{$tag->titel}}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
@foreach($item->tags as $tag)
|
||||
<li class="category">
|
||||
<a title="{{$tag->titel}}"
|
||||
href="{{route('nieuws.tag', ['tag' => $tag->slug])}}"
|
||||
class="over_image">{{$tag->titel}}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<h5 class="post_title"><a href="{{url($item->url)}}"
|
||||
title="{{$item->title}}">{!!$item->title!!}</a></h5>
|
||||
title="{{$item->title}}">{!!$item->title!!}</a></h5>
|
||||
<?php
|
||||
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
|
||||
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
|
||||
@@ -136,13 +136,10 @@
|
||||
<div class="grey_background">
|
||||
<div class="body_container row">
|
||||
@if(!isset($disableBanners) || !$disableBanners)
|
||||
<div class="col-12">
|
||||
<div class="d-none d-md-block" style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
|
||||
- Advertentie -
|
||||
<div class="homepage-body-banners d-none d-md-flex justify-content-center mb-4">
|
||||
<ins data-revive-zoneid="3" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
<ins data-revive-zoneid="4" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
</div>
|
||||
<div id="nhgooi_homepage_top" class="d-none d-md-block" style="width: 728px; height: 90px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
|
||||
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_homepage_top",targetId: "nhgooi_homepage_top",adShownCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-12 col-md content_container">
|
||||
<div class="row">
|
||||
@@ -175,30 +172,32 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6">
|
||||
<a href="{{$url}}" title="{{$podcast->title}}">
|
||||
<img src="{{($hasImage = $podcast->image && $podcast->image->url) ? $imgBase . $podcast->image->url : '/images/noimage.png'}}"/>
|
||||
<div class="sentence">
|
||||
<?php
|
||||
$sentence = [];
|
||||
if ($hasImage) {
|
||||
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
|
||||
} elseif (isset($podcast->image->title) && $podcast->image->title) {
|
||||
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
|
||||
}
|
||||
if (isset($podcast->image->author) && $podcast->image->author) {
|
||||
$sentence[] = '<span class="author">' . $podcast->image->author . '</span>';
|
||||
}
|
||||
$sentence = join('<span class="separator">|</span>', $sentence);
|
||||
?>
|
||||
{!!$sentence!!}
|
||||
</div>
|
||||
<img src="{{($hasImage = $podcast->image && $podcast->image->url) ? $imgBase . $podcast->image->url : '/images/noimage.png'}}"/>
|
||||
<div class="sentence">
|
||||
<?php
|
||||
$sentence = [];
|
||||
if ($hasImage) {
|
||||
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
|
||||
} elseif (isset($podcast->image->title) && $podcast->image->title) {
|
||||
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
|
||||
}
|
||||
if (isset($podcast->image->author) && $podcast->image->author) {
|
||||
$sentence[] = '<span class="author">' . $podcast->image->author . '</span>';
|
||||
}
|
||||
$sentence = join('<span class="separator">|</span>', $sentence);
|
||||
?>
|
||||
{!!$sentence!!}
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<h2 class="post_title"><a href="{{$url}}" title="{{$podcast->title}}">{!!$podcast->title!!}</a></h2>
|
||||
<h2 class="post_title"><a href="{{$url}}"
|
||||
title="{{$podcast->title}}">{!!$podcast->title!!}</a></h2>
|
||||
<div class="sub_title">
|
||||
@if ($podcast->program)
|
||||
<a class="program_name" href="{{ route('programma') . $podcast->program->url }}"
|
||||
<a class="program_name"
|
||||
href="{{ route('programma') . $podcast->program->url }}"
|
||||
title="{{$podcast->program->name}}">{{$podcast->program->name}}</a>
|
||||
@endif
|
||||
<span class="post_date" title="{{Formatter::relativeDate($podcast->created)}}">
|
||||
@@ -217,11 +216,9 @@
|
||||
<div class="col-12 col-md-auto sidebar">
|
||||
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_homepage_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets.banner_sidebar')
|
||||
|
||||
@include('widgets/contact', [])
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_homepage_side2', 'ad_sidebarId' => 'nhgooi_sidebar2'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<script type="text/javascript" src="//www.cookieconsent.com/releases/3.1.0/cookie-consent.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palette":"light","language":"nl","website_name":"NH Gooi","cookies_policy_url":"https://www.nhnieuws.nl/privacyverklaring","change_preferences_selector":"#changePreferences"});
|
||||
cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palette":"light","language":"nl","website_name":"NH Gooi","cookies_policy_url":"/privacy-verklaring","change_preferences_selector":"#changePreferences"});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -13,9 +13,7 @@ cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palet
|
||||
<!-- End Google Tag Manager -->
|
||||
|
||||
@if(!isset($disableBanners) || !$disableBanners)
|
||||
<script type="text/javascript" src="https://cdn.optoutadvertising.com/script/ootag.v2.js"></script><script>var ootag =
|
||||
ootag || {}; ootag.queue = ootag.queue || [];ootag.queue.push(function () { ootag.initializeOo({
|
||||
publisher: 4, onlyNoConsent: 1, consentTimeOutMS: 500 });});</script>
|
||||
<script async src="{{ env('ADS_URL') }}www/delivery/asyncjs.php"></script>
|
||||
@endif
|
||||
|
||||
<noscript>ePrivacy and GPDR Cookie Consent by <a href="https://www.CookieConsent.com/" rel="nofollow noopener">Cookie Consent</a></noscript>
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
</div>
|
||||
|
||||
@if(!isset($disableBanners) || !$disableBanners)
|
||||
<div id="nhgooi_header_top" class="advertisement" style="margin: 11px auto 0 auto;background-color: #efefef;"></div>
|
||||
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_homepage_header",targetId: "nhgooi_header_top",filledCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
|
||||
<ins data-revive-zoneid="1" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@@ -89,6 +88,12 @@
|
||||
@include('widgets.menu')
|
||||
</div>
|
||||
|
||||
@if(!isset($disableBanners) || !$disableBanners)
|
||||
<div class="mobile-banner-fullwidth d-flex d-md-none justify-content-center mt-4">
|
||||
<ins data-revive-zoneid="6" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<div class="page @yield('page_container_class')">
|
||||
@@ -101,10 +106,10 @@
|
||||
<div class="footer_menu">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-3">
|
||||
<h4 class="box_header"><span>NH Gooi</span></h4>
|
||||
<h4 class="box_header"><span>NHGooi</span></h4>
|
||||
<p class="about">
|
||||
NH Gooi is de streekomroep voor Gooi & Vechtstreek. Wij brengen nieuws en achtergronden
|
||||
op onze website, radio en televisie. Daarnaast brengen we boeiende en belangrijke podcasts
|
||||
NHGooi is de streekomroep voor Gooi & Vechtstreek. Wij brengen nieuws en achtergronden
|
||||
op onze website, radio en televisie. Daarnaast brengen we boeiende en belangrijke podcasts
|
||||
en een gevariëerd programma-aanbod op al onze media-kanalen.
|
||||
</p>
|
||||
</div>
|
||||
@@ -159,7 +164,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© NH Gooi
|
||||
© NHGooi
|
||||
<a class="scroll_top" href="#top" title="Scroll to top"><i class="fa-solid fa-angle-up"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,6 +191,7 @@
|
||||
<script type="text/javascript" src="/js/jquery.prettyPhoto.js"></script>
|
||||
<script type="text/javascript" src="/js/jquery.carouFredSel-6.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="/js/functions.js"></script>
|
||||
<script type="text/javascript" src="/js/wavesurfer.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).resize(function () {
|
||||
// Fix sticky for mobile menu indicator
|
||||
@@ -202,7 +208,7 @@
|
||||
function openPlayerInNewScreen() {
|
||||
$(".player").click(function (e) {
|
||||
e.preventDefault();
|
||||
window.open($(this).attr('href'), '_player', 'width=550,height=500,titlebar,close');
|
||||
window.open($(this).attr('href'), '_player', 'width=550,height=600,titlebar,close');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@extends('layouts/master')
|
||||
|
||||
@section('content_class')box
|
||||
@section('content_class')
|
||||
box
|
||||
@endsection
|
||||
|
||||
@section('page')
|
||||
@@ -57,13 +58,11 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
|
||||
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
|
||||
|
||||
@include('widgets/contact', [])
|
||||
@include('widgets.banner_sidebar')
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar2 ?? 'nhgooi_section_side2', 'ad_sidebarId' => 'nhgooi_sidebar2'])
|
||||
@include('widgets/contact', [])
|
||||
@show
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<a href="javascript:window.close();" class="close btn"><span class='fa fa-times fa-fw'></span> Venster sluiten</a>
|
||||
<p class="logo"><a href="{{ url('/') }}"><img src="{{ url( 'images/logo-NHGooi.svg' )}}"></a></p>
|
||||
|
||||
@if(false && $isStream)
|
||||
<p>Wegens een technisch probleem is NH Gooi momenteel niet via Internet te beluisteren. Onze excuses voor het
|
||||
@if(isset($notAvailable) && $notAvailable)
|
||||
<p>Helaas is de door u gekozen audio momenteel niet via Internet te beluisteren. Onze excuses voor het
|
||||
ongemak.</p>
|
||||
<p>In Hilversum, Huizen en de BEL-gemeenten zijn wij te ontvangen op 92.0 FM of 105.1 FM.</p>
|
||||
@else
|
||||
@@ -36,9 +36,16 @@
|
||||
</p>
|
||||
@endif
|
||||
<p>
|
||||
<audio controls autoplay="true">
|
||||
{{-- <audio controls autoplay="true">
|
||||
<source src="{{$source}}" type="audio/mp3"/>
|
||||
</audio>
|
||||
</audio> --}}
|
||||
|
||||
@include('widgets.audioplayer', [
|
||||
'source' => $source,
|
||||
'isStream' => $isStream,
|
||||
'lengte' => $lengte,
|
||||
'waveform' => $waveform
|
||||
])
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -130,6 +137,7 @@
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript" src="/js/jquery-3.7.1.min.js"></script>
|
||||
<script type="text/javascript" src="/js/wavesurfer.min.js"></script>
|
||||
<script>
|
||||
function updateOnAir() {
|
||||
$.ajax({
|
||||
@@ -163,4 +171,3 @@
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@include('widgets.mediaplayer')
|
||||
|
||||
@@ -14,13 +14,9 @@
|
||||
<div class="grey_background">
|
||||
<div class="body_container row">
|
||||
@if(!isset($disableBanners) || !$disableBanners)
|
||||
<div class="col-12">
|
||||
<div style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
|
||||
- Advertentie -
|
||||
<div class="col-12">
|
||||
<ins data-revive-zoneid="5" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
</div>
|
||||
<div id="nhgooi_article_top" style="width: 728px; height: 90px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
|
||||
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_article_top",targetId: "nhgooi_article_top",filledCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-12 col-md content_container">
|
||||
<div class="row">
|
||||
@@ -45,9 +41,9 @@
|
||||
<div class="col-12 col-md-auto sidebar">
|
||||
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
|
||||
|
||||
@include('widgets/contact', [])
|
||||
@include('widgets.banner_sidebar')
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_article_side' ?? false, 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets/contact', [])
|
||||
|
||||
<div class="podcast_items">
|
||||
<h4 class="box_header small"><span>Fragment gemist</span></h4>
|
||||
@@ -55,8 +51,6 @@
|
||||
@include('partial/podcastitems', ['showTime' => false, 'showImage' => false, 'podcasts' => $podcasts, 'isPodcast' => false])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_article_side2' ?? false, 'ad_sidebarId' => 'nhgooi_sidebar2'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -87,8 +87,10 @@
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if(is_array($news->content))
|
||||
@include('partial/nh_story', ['content' => $news->content])
|
||||
@if($type == "nhnieuws")
|
||||
@include('partial/nh_story', ['content' => $news->content])
|
||||
@elseif($type == "artikel")
|
||||
@include('partial/block_story', ['content' => $news->content])
|
||||
@else
|
||||
<div class="text">
|
||||
<p>{!!$news->content!!}</p>
|
||||
|
||||
161
resources/views/partial/block_story.blade.php
Normal file
161
resources/views/partial/block_story.blade.php
Normal file
@@ -0,0 +1,161 @@
|
||||
@foreach($content as $block)
|
||||
@if($block->type == "headerRichA")
|
||||
@php($block->data->image->url = isset($block->data->image->crops)
|
||||
? $block->data->image->crops->{'16:9'}->{'1600'}
|
||||
: $block->data->image->crop)
|
||||
<a href="{{$block->data->image->url}}" class="post_image page_margin_top prettyPhoto" rel="prettyPhoto"
|
||||
title="{{$block->data->image->title}}">
|
||||
<img src="{{$block->data->image->url}}" alt="{{$block->data->image->title}}">
|
||||
</a>
|
||||
<div class="sentence margin_top_10">
|
||||
<span class="text">{{$block->data->image->title}}</span>
|
||||
@if($block->data->image->author)
|
||||
<span class="author">{{$block->data->image->author}}</span>
|
||||
@endif
|
||||
</div>
|
||||
@elseif($block->type == "paragraph")
|
||||
<div class="text">{!!$block->data->text!!}</div>
|
||||
@elseif($block->type == "intro")
|
||||
<h3 class="excerpt">{!!strip_tags($block->data->text)!!}</h3>
|
||||
@elseif($block->type == "info")
|
||||
@if(strpos($block->data->text, "Meer nieuws uit 't Gooi?") === false)
|
||||
<div class="info" style="background-color: {{$block->data->color}};">{!!($block->data->text)!!}</div>
|
||||
@endif
|
||||
@elseif($block->type == "quote")
|
||||
<blockquote>
|
||||
{!!$block->data->text!!}
|
||||
<div class="author">{{$block->data->caption}}</div>
|
||||
</blockquote>
|
||||
@elseif($block->type == "image")
|
||||
<?php
|
||||
if(isset($block->data->image->imageWide))
|
||||
$image = $block->data->image->imageWide;
|
||||
else if(isset($block->data->image->crop))
|
||||
$image = $block->data->image->crop;
|
||||
else if(isset($block->data->image->crops) && isset($block->data->image->crops->{'16:9'}))
|
||||
foreach($block->data->image->crops->{'16:9'} as $image) break;
|
||||
else if(isset($block->data->image->imageHigh))
|
||||
$image = $block->data->image->imageHigh;
|
||||
else $image = null;
|
||||
?>
|
||||
@if($image)
|
||||
<a class="post_image page_margin_top prettyPhoto" rel="prettyPhoto" href="{{$image}}"
|
||||
title="{{$block->data->image->title}} © {{$block->data->image->author}}">
|
||||
<img src="{{$image}}" class="attachment-small-slider-thumb size-small-slider-thumb wp-post-image"
|
||||
alt="{{$block->data->image->title}}" title="" style="display: block;">
|
||||
</a>
|
||||
<div class="sentence">
|
||||
<?php
|
||||
$sentence = [];
|
||||
if (isset($block->data->image->caption) && $block->data->image->caption) {
|
||||
$sentence[] = '<span class="text">' . $block->data->image->caption . '</span>';
|
||||
} elseif (isset($block->data->image->title) && $block->data->image->title) {
|
||||
$sentence[] = '<span class="text">' . $block->data->image->title . '</span>';
|
||||
}
|
||||
if (isset($block->data->image->author) && $block->data->image->author) {
|
||||
$sentence[] = '<span class="author">' . $block->data->image->author . '</span>';
|
||||
}
|
||||
$sentence = join('<span class="separator">|</span>', $sentence);
|
||||
?>
|
||||
{!!$sentence!!}
|
||||
</div>
|
||||
@endif
|
||||
@elseif($block->type == "video" || $block->type == "headerVideo")
|
||||
@include('widgets/mediaplayer')
|
||||
<?php
|
||||
$attr = '';
|
||||
if (isset($block->data->video->images[0]->imageMedia) && $block->data->video->images[0]->imageMedia) {
|
||||
$attr = ' poster="' . $block->data->video->images[0]->imageMedia . '"';
|
||||
}
|
||||
?>
|
||||
<video controls{!!$attr!!}>
|
||||
@foreach($block->data->video->streams as $stream)
|
||||
<source src="{!!$stream->stream_url!!}" type="application/x-mpegurl" />
|
||||
@endforeach
|
||||
</video>
|
||||
<div class="sentence">
|
||||
<span class="author">{{$block->data->video->author}}</span>
|
||||
</div>
|
||||
@elseif($block->type == "carousel")
|
||||
<div class="horizontal_carousel_container gallery">
|
||||
<ul class="horizontal_carousel visible-5 autoplay-1 scroll-1 navigation-1 easing-easeInOutQuint duration-750">
|
||||
@foreach($block->data->items as $image)
|
||||
<?php
|
||||
if(isset($image->image->imageWide))
|
||||
$img = $image->image->imageWide;
|
||||
else if(isset($block->data->image->crop))
|
||||
$image = $block->data->image->crop;
|
||||
else if(isset($image->image->crops) && isset($image->image->crops->{'16:9'}))
|
||||
foreach($image->image->crops->{'16:9'} as $img) break;
|
||||
else if(isset($image->image->imageHigh))
|
||||
$img = $image->image->imageHigh;
|
||||
else $img = null;
|
||||
?>
|
||||
@if($img)
|
||||
<li>
|
||||
<a href="{{$img}}" class="post_image prettyPhoto" rel="prettyPhoto[gallery]"
|
||||
title="{{$image->image->title}} © {{$image->image->author}}">
|
||||
<img src="{{$img}}" alt="{{$image->image->title}}" title="{{$image->image->title}}">
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@elseif($block->type == "oembed")
|
||||
<div class="oembed" data-url="{{$block->data->url}}">{!!$block->data->html!!}</div>
|
||||
@elseif($block->type == "podcast" && $block->data->id == $news->podcast?->id)
|
||||
@include('widgets/podcastplayer', ['podcast' => $news->podcast])
|
||||
<? $news->podcast = null; // Avoid adding the player again ?>
|
||||
@elseif($block->type == 'article' && count($block->data->articles) && $block->data->articles[0]->published)
|
||||
<div class="block">
|
||||
<h4 class="box_header"><span>{{ $block->data->title }}</span></h4>
|
||||
<div class="box full-width">
|
||||
<ul id="items-more-news" class="blog">
|
||||
@foreach($block->data->articles as $article)
|
||||
<? if(!isset($article->published)) continue;
|
||||
$article->published = new \DateTime($article->published); ?>
|
||||
<li class="post">
|
||||
<div class="row">
|
||||
@if($article->image)
|
||||
<div class="col-4">
|
||||
<a href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
|
||||
title="{{ $article->title }}">
|
||||
<img src="{{ $article->image[0] == '/' ? '' : '/' }}{{ $article->image }}" alt="{{ $article->image_title }}">
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-8">
|
||||
<h2 class="post_title"><a class="clipText clipText-3"
|
||||
href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
|
||||
title="{!! $article->title !!}">{!! $article->title !!}</a></h2>
|
||||
<span class="post_date" title="Vandaag om 09:30">
|
||||
<i class="fa-regular fa-clock"></i>
|
||||
{{Formatter::relativeDate($article->published)}} om {{$article->published->format('H:i')}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@elseif($block->type == 'iframe')
|
||||
<iframe src="{{ $block->data->url }}" class="article-iframe" id="{{ $id = uniqid('iframe_') }}"></iframe>
|
||||
<style>
|
||||
@if(isset($block->data->ratio))
|
||||
#{{ $id }}.article-iframe {
|
||||
aspect-ratio: {{ str_replace(":", "/", $block->data->ratio) }};
|
||||
}
|
||||
@endif
|
||||
|
||||
@if(isset($block->data->ratioMobile))
|
||||
@media (max-width: 768px) {
|
||||
#{{ $id }}.article-iframe {
|
||||
aspect-ratio: {{ str_replace(":", "/", $block->data->ratioMobile) }};
|
||||
}
|
||||
}
|
||||
@endif
|
||||
</style>
|
||||
@endif
|
||||
@endforeach
|
||||
@@ -121,7 +121,7 @@
|
||||
<div class="col-4">
|
||||
<a href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
|
||||
title="{{ $article->title }}">
|
||||
<img src="{{ $article->image }}" alt="{{ $article->image_title }}">
|
||||
<img src="{{ $article->image[0] == '/' ? '' : '/' }}{{ $article->image }}" alt="{{ $article->image_title }}">
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@@ -140,5 +140,22 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@elseif($block->type == 'iframe')
|
||||
<iframe src="{{ $block->url }}" class="article-iframe" id="{{ $id = uniqid('iframe_') }}"></iframe>
|
||||
<style>
|
||||
@if(isset($block->ratio))
|
||||
#{{ $id }}.article-iframe {
|
||||
aspect-ratio: {{ str_replace(":", "/", $block->ratio) }};
|
||||
}
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@if(isset($block->ratioMobile))
|
||||
@media (max-width: 768px) {
|
||||
#{{ $id }}.article-iframe {
|
||||
aspect-ratio: {{ str_replace(":", "/", $block->ratioMobile) }};
|
||||
}
|
||||
}
|
||||
@endif
|
||||
</style>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
@include('widgets/mediaplayer')
|
||||
|
||||
@section('title')
|
||||
@if($podcast)
|
||||
{{ $podcast->title }}
|
||||
@elseif($isPodcast)
|
||||
NH Gooi Podcast
|
||||
@else
|
||||
Fragment gemist
|
||||
@endif
|
||||
@if($podcast)
|
||||
{{ $podcast->title }}
|
||||
@elseif($isPodcast)
|
||||
NH Gooi Podcast
|
||||
@else
|
||||
Fragment gemist
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('page_class')
|
||||
@@ -20,11 +20,11 @@
|
||||
<ul class="bread_crumb">
|
||||
<li><a title="Home" href="/">Home</a></li>
|
||||
<li class="separator"><i class="fa-solid fa-chevron-right"></i></li>
|
||||
@if($isPodcast)
|
||||
<li>NH Gooi podcast</li>
|
||||
@else
|
||||
<li><a title="Home" href="/gemist/fragment">Fragment gemist</a></li>
|
||||
@endif
|
||||
@if($isPodcast)
|
||||
<li>NH Gooi podcast</li>
|
||||
@else
|
||||
<li><a title="Home" href="/gemist/fragment">Fragment gemist</a></li>
|
||||
@endif
|
||||
<li class="separator"><i class="fa-solid fa-chevron-right"></i></li>
|
||||
@if($podcast && $podcast->program)
|
||||
<li><a title="{{$podcast->program->name}}"
|
||||
@@ -112,14 +112,19 @@
|
||||
</ul>
|
||||
|
||||
<div class="announcement">
|
||||
<audio controls>
|
||||
<source src="{{$streamUrl}}" type="audio/mpeg"/>
|
||||
</audio>
|
||||
@include("widgets.audioplayer", [
|
||||
'isStream' => false,
|
||||
'source' => $streamUrl,
|
||||
'lengte' => $podcast->duration / 1000,
|
||||
'waveform' => $podcast->waveform
|
||||
])
|
||||
|
||||
<div class="clearfix">
|
||||
<a class="action_button btn" href="{{$audioUrl}}" title="Download dit fragment als MP3">
|
||||
<a class="action_button btn" href="{{$audioUrl}}"
|
||||
title="Download dit fragment als MP3">
|
||||
<span>Download fragment</span>
|
||||
</a>
|
||||
<a class="action_button btn player" href="{{$popoutUrl}}">
|
||||
<a class="action_button btn player" href="{{$popoutUrl}}" onclick="pause()">
|
||||
<span>Luister in nieuw venster</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -156,7 +161,8 @@
|
||||
<div data-tabs>
|
||||
<div class="tabs">
|
||||
<h4 data-tab-content-id="tab_more_fragmenten"
|
||||
class="box_header small flex-grow-1 active"><span>Meer {{$isPodcast ? 'afleveringen' : 'fragmenten'}}</span>
|
||||
class="box_header small flex-grow-1 active">
|
||||
<span>Meer {{$isPodcast ? 'afleveringen' : 'fragmenten'}}</span>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="tab_more_fragmenten" class="box tab_content podcast_items active">
|
||||
@@ -170,8 +176,8 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets.banner_sidebar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@@ -54,13 +54,14 @@
|
||||
</p>
|
||||
@else
|
||||
<p class="page_body">Hele uitzendingen kunt u binnen twee weken terugluisteren via <a
|
||||
href="{{route('gemist.programma')}}">programma gemist</a>.<br /><br />
|
||||
href="{{route('gemist.programma')}}">programma gemist</a>.<br/><br/>
|
||||
@endif
|
||||
|
||||
@if(isset($podcasts))
|
||||
|
||||
<div class="clearfix podcast_items">
|
||||
@include('partial/podcastitems', [
|
||||
'id' => null,
|
||||
'li' => [
|
||||
'class' => 'col-12 col-md-6'
|
||||
],
|
||||
@@ -109,7 +110,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets.banner_sidebar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@extends('layouts/full')
|
||||
|
||||
@section('title')
|
||||
@if(isset($program))
|
||||
{{ $program->name }}
|
||||
@else
|
||||
NH Gooi Podcast
|
||||
@endif
|
||||
@if(isset($program))
|
||||
{{ $program->name }}
|
||||
@else
|
||||
NH Gooi Podcast
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('page_class')
|
||||
@@ -40,18 +40,18 @@
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if($podcasts)
|
||||
@if($podcasts)
|
||||
|
||||
<div class="page_layout clearfix">
|
||||
<div class="grid" id="items">
|
||||
@include('partial/podcastdirectitems', ['podcasts' => array_slice($podcasts, 0, 2), 'isPodcast' => $isPodcast])
|
||||
</div><!--/.row-->
|
||||
</div>
|
||||
@else
|
||||
<div class="box full-width">
|
||||
<p class="page_body">Er zijn geen items beschikbaar.</p>
|
||||
</div>
|
||||
@endif
|
||||
<div class="page_layout clearfix">
|
||||
<div class="grid" id="items">
|
||||
@include('partial/podcastdirectitems', ['podcasts' => array_slice($podcasts, 0, 2), 'isPodcast' => $isPodcast])
|
||||
</div><!--/.row-->
|
||||
</div>
|
||||
@else
|
||||
<div class="box full-width">
|
||||
<p class="page_body">Er zijn geen items beschikbaar.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-12 col-md-auto sidebar">
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets.banner_sidebar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
@extends('layouts/full')
|
||||
|
||||
@section('title')
|
||||
Programma gemist
|
||||
Programma gemist
|
||||
@endsection
|
||||
|
||||
@section('page_class')news_post post_container @endsection
|
||||
@section('page_class')
|
||||
news_post post_container
|
||||
@endsection
|
||||
|
||||
@section('breadcrumb')
|
||||
@if(isset($program))
|
||||
@@ -51,7 +53,8 @@
|
||||
class="btn btn-info">Programmainfo</a>
|
||||
</p>
|
||||
@else
|
||||
<p class="page_body">U kunt programma's terugluisteren tot twee weken na uitzending. Items blijven onbeperkt beschikbaar via <a href="{{route('gemist.fragment')}}">fragment gemist</a>.<br /><br />
|
||||
<p class="page_body">U kunt programma's terugluisteren tot twee weken na uitzending. Items blijven
|
||||
onbeperkt beschikbaar via <a href="{{route('gemist.fragment')}}">fragment gemist</a>.<br/><br/>
|
||||
@endif
|
||||
|
||||
@if(isset($programs))
|
||||
@@ -106,20 +109,31 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
|
||||
@include('widgets.banner_sidebar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
@keyframes tilt-shaking {
|
||||
0% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(5deg); }
|
||||
50% { transform: rotate(0deg); }
|
||||
75% { transform: rotate(-5deg); }
|
||||
100% { transform: rotate(0deg); }
|
||||
}
|
||||
.post_container .post_tags li a {
|
||||
animation: tilt-shaking 1s linear infinite;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
@keyframes tilt-shaking {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.post_container .post_tags li a {
|
||||
animation: tilt-shaking 1s linear infinite;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
@if ($ad_sidebar && (!isset($disableBanners) || !$disableBanners))
|
||||
<div style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
|
||||
- Advertentie -
|
||||
</div>
|
||||
<div id="{{$ad_sidebarId}}" style="width: 100%;height: 275px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
|
||||
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "{{$ad_sidebar}}",targetId: "{{$ad_sidebarId}}",adShownCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
|
||||
@endif
|
||||
176
resources/views/widgets/audioplayer.blade.php
Normal file
176
resources/views/widgets/audioplayer.blade.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php $id = uniqid('player_'); ?>
|
||||
<div class="audioplayer" id="{{ $id }}">
|
||||
@if(!$isStream)
|
||||
<div class="waveform">
|
||||
<div class="time">0:00</div>
|
||||
<div class="duration">0:00</div>
|
||||
<div class="hover"></div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="volume-controls">
|
||||
<button class="btn-toggle-mute" type="button" onclick="toggleMute()">
|
||||
<span class="fa fa-volume-high"></span>
|
||||
</button>
|
||||
<input class="volume-slider" type="range" min="0" max="1" step="0.01" value="1"
|
||||
onchange="setVolume( this.value )" />
|
||||
</div>
|
||||
|
||||
<div class="audio-controls">
|
||||
@if(!$isStream)
|
||||
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(-60)">
|
||||
<span class="fa fa-backward-fast"></span>
|
||||
<label>-60 s</label>
|
||||
</button>
|
||||
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(-10)">
|
||||
<span class="fa fa-backward-step"></span>
|
||||
<label>-10 s</label>
|
||||
</button>
|
||||
@endif
|
||||
<button class="btn btn-play" type="button" onclick="playPause()">
|
||||
<span class="play-button-icon fa fa-play"></span>
|
||||
<label class="play-button-label">Afspelen</label>
|
||||
</button>
|
||||
@if(!$isStream)
|
||||
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(10)">
|
||||
<span class="fa fa-forward-step"></span>
|
||||
<label>+10 s</label>
|
||||
</button>
|
||||
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(60)">
|
||||
<span class="fa fa-forward-fast"></span>
|
||||
<label>+60 s</label>
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($isStream)
|
||||
|
||||
<audio id="audio_{{ $id }}">
|
||||
<source src="{{ $source }}" type="audio/mp3" />
|
||||
</audio>
|
||||
|
||||
<script>
|
||||
var player_{{ $id }};
|
||||
|
||||
setVolume = volume => player_{{ $id }}.volume = volume;
|
||||
function toggleMute () {
|
||||
var isMuted = !player_{{ $id }}.muted;
|
||||
player_{{ $id }}.muted = isMuted;
|
||||
if(isMuted) {
|
||||
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-xmark"></span>');
|
||||
$('#{{ $id }} .volume-slider').attr('disabled', 'disabled');
|
||||
} else {
|
||||
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-high"></span>');
|
||||
$('#{{ $id }} .volume-slider').removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
pause = () => player_{{ $id }}.pause();
|
||||
|
||||
function playPause() {
|
||||
var player = player_{{ $id }};
|
||||
if (player.paused) {
|
||||
player.play();
|
||||
} else {
|
||||
player.pause();
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener("DOMContentLoaded", function() {
|
||||
var player = document.getElementById( "audio_{{ $id }}");
|
||||
player_{{ $id }} = player;
|
||||
|
||||
$(player_{{ $id }}).on('play', () => {
|
||||
$('#{{ $id }} .play-button-icon').addClass('fa-pause').removeClass('fa-play');
|
||||
$('#{{ $id }} .play-button-label').text('Pauzeren');
|
||||
})
|
||||
$(player_{{ $id }}).on('pause', () => {
|
||||
$('#{{ $id }} .play-button-icon').addClass('fa-play').removeClass('fa-pause');
|
||||
$('#{{ $id }} .play-button-label').text('Verder spelen');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@else
|
||||
|
||||
<script>
|
||||
var wavesurfer_{{ $id }};
|
||||
|
||||
setVolume = volume => wavesurfer_{{ $id }}.setVolume( volume );
|
||||
playPause = () => wavesurfer_{{ $id }}.playPause();
|
||||
pause = () => wavesurfer_{{ $id }}.pause();
|
||||
|
||||
function toggleMute () {
|
||||
var isMuted = !wavesurfer_{{ $id }}.getMuted();
|
||||
wavesurfer_{{ $id }}.setMuted(isMuted);
|
||||
if(isMuted) {
|
||||
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-xmark"></span>');
|
||||
$('#{{ $id }} .volume-slider').attr('disabled', 'disabled');
|
||||
} else {
|
||||
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-high"></span>');
|
||||
$('#{{ $id }} .volume-slider').removeAttr('disabled');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addEventListener("DOMContentLoaded", function() {
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
// Create the waveform
|
||||
wavesurfer_{{ $id }} = WaveSurfer.create({
|
||||
container: '#{{ $id }} .waveform',
|
||||
waveColor: '#3A96EE',
|
||||
progressColor: '#0118A1',
|
||||
height: 50,
|
||||
barWidth: 1,
|
||||
@if(isset($lengte))
|
||||
duration: {{ $lengte }},
|
||||
@endif
|
||||
@if($waveform)
|
||||
peaks: {{ json_encode($waveform->data) }},
|
||||
normalize: true,
|
||||
@endif
|
||||
|
||||
url: '{{ $source }}',
|
||||
});
|
||||
|
||||
// Play/pause on click
|
||||
wavesurfer_{{ $id }}.on('click', () => {
|
||||
wavesurfer_{{ $id }}.play();
|
||||
})
|
||||
wavesurfer_{{ $id }}.on('play', () => {
|
||||
$('#{{ $id }} .play-button-icon').addClass('fa-pause').removeClass('fa-play');
|
||||
$('#{{ $id }} .play-button-label').text('Pauzeren');
|
||||
})
|
||||
wavesurfer_{{ $id }}.on('pause', () => {
|
||||
$('#{{ $id }} .play-button-icon').addClass('fa-play').removeClass('fa-pause');
|
||||
$('#{{ $id }} .play-button-label').text('Verder spelen');
|
||||
})
|
||||
|
||||
// Hover effect
|
||||
{
|
||||
const hover = document.querySelector('#{{ $id }} .hover')
|
||||
const waveform = document.querySelector('#{{ $id }} .waveform')
|
||||
waveform.addEventListener('pointermove', (e) => (hover.style.width = `${e.offsetX}px`))
|
||||
}
|
||||
|
||||
// Current time & duration
|
||||
{
|
||||
const formatTime = (seconds) => {
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const secondsRemainder = Math.round(seconds) % 60
|
||||
const paddedSeconds = `0${secondsRemainder}`.slice(-2)
|
||||
return `${minutes}:${paddedSeconds}`
|
||||
}
|
||||
|
||||
const timeEl = document.querySelector('#{{ $id }} .time')
|
||||
const durationEl = document.querySelector('#{{ $id }} .duration')
|
||||
wavesurfer_{{ $id }}.on('decode', (duration) => (durationEl.textContent = formatTime(duration)))
|
||||
wavesurfer_{{ $id }}.on('timeupdate', (currentTime) => (timeEl.textContent = formatTime(currentTime)))
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@endif
|
||||
5
resources/views/widgets/banner_sidebar.blade.php
Normal file
5
resources/views/widgets/banner_sidebar.blade.php
Normal file
@@ -0,0 +1,5 @@
|
||||
@if (!isset($disableBanners) || !$disableBanners)
|
||||
<div class="d-flex justify-content-center my-4">
|
||||
<ins data-revive-zoneid="2" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
|
||||
</div>
|
||||
@endif
|
||||
@@ -2,8 +2,7 @@
|
||||
<img class="logo-whatsapp" src="/images/logo-whatsapp.png"/>
|
||||
<h2>Contact met de redactie</h2>
|
||||
<p>Heb jij een tip voor onze streekredactie? Bel of app de tiplijn:
|
||||
<a href="tel:06 - 42 91 36 37" target="_blank">06 - 42 91 36 37</a>, stuur een
|
||||
<a href="mailto:info@nhgooi.nl">mail</a> of kom langs op de Gooise Brink,
|
||||
Kerkstraat 63/27 in Hilversum</p>
|
||||
<a href="tel:0356424774" target="_blank">035 - 64 24 774</a>, of stuur een
|
||||
<a href="mailto:info@nhgooi.nl">mail</a>.</p>
|
||||
<a class="read_more" href="{{url('contact')}}">Contactinformatie <i class="fa-solid fa-angle-right"></i></a>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"Podcasts" => array(
|
||||
"" => "/podcast",
|
||||
"NH Gooi Spreekuur" => "/podcast/1091/nh-gooi-spreekuur",
|
||||
"Gooise Mythes Ontrafeld" => "/podcast/1106/gooise-mythes-ontrafeld",
|
||||
"NH Gooi Wijsneuzen" => "/podcast/1098/nh-gooi-wijsneuzen",
|
||||
"Hilversum in de oorlog" => "/podcast/1097/hilversum-in-de-oorlog",
|
||||
),
|
||||
@@ -145,4 +146,3 @@ function buildMenu($menu, $ismobile)
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<h4 data-tab-content-id="tab_gooi_tv_live" class="box_header {{$headerClass ?? ''}}">
|
||||
<span>NH Gooi TV live</span></h4>
|
||||
</div>
|
||||
<div id="tab_gooi_radio_live" class="tab_content active box radio_box">
|
||||
<div id="tab_gooi_radio_live" class="tab_content active box radio_box mb-0">
|
||||
<img class="logo-radio" src="/images/logo-NHGooi-radio.svg"/>
|
||||
@include('widgets.nustraks')
|
||||
<a class="btn" href="/gids">Programmering</a>
|
||||
@@ -13,7 +13,7 @@
|
||||
<a class="btn player" href="/luister/live">Luister live</a>
|
||||
<a class="btn" href="/kijk/live">Kijk live mee</a>
|
||||
</div>
|
||||
<div id="tab_gooi_tv_live" class="tab_content box radio_box">
|
||||
<div id="tab_gooi_tv_live" class="tab_content box radio_box mb-0">
|
||||
<img class="logo-radio" src="/images/logo-NHGooi-televisie.svg"/>
|
||||
<h2 class="post_title">Live</h2>
|
||||
@include('widgets.mediaplayer')
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
@endif
|
||||
<p class="now-playing-header-small">
|
||||
<strong>Nu:</strong>
|
||||
<span class="title"></span> -
|
||||
<span class="artist"></span>
|
||||
<span class="artist"></span> -
|
||||
<span class="title"></span>
|
||||
</p>
|
||||
<script type="text/javascript" src="/js/jquery-3.7.1.min.js"></script>
|
||||
<script>
|
||||
|
||||
108
vendor/composer/ClassLoader.php
vendored
108
vendor/composer/ClassLoader.php
vendored
@@ -45,35 +45,34 @@ class ClassLoader
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
@@ -81,8 +80,7 @@ class ClassLoader
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
@@ -90,21 +88,20 @@ class ClassLoader
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
@@ -113,7 +110,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
@@ -125,8 +122,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
@@ -134,8 +130,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
@@ -143,8 +138,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
@@ -152,8 +146,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
@@ -161,8 +154,7 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -179,24 +171,25 @@ class ClassLoader
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,19 +198,19 @@ class ClassLoader
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -226,9 +219,9 @@ class ClassLoader
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
@@ -236,17 +229,18 @@ class ClassLoader
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
@@ -256,18 +250,18 @@ class ClassLoader
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -276,8 +270,8 @@ class ClassLoader
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -294,8 +288,8 @@ class ClassLoader
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
@@ -429,7 +423,8 @@ class ClassLoader
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
(self::$includeFile)($file);
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -480,9 +475,9 @@ class ClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
@@ -560,7 +555,10 @@ class ClassLoader
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function initializeIncludeClosure(): void
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
@@ -574,8 +572,8 @@ class ClassLoader
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = static function($file) {
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
};
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/composer/autoload_real.php
vendored
6
vendor/composer/autoload_real.php
vendored
@@ -34,15 +34,15 @@ class ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit5216a35d72a5119d2f4646cd700f802d::$files;
|
||||
$requireFile = static function ($fileIdentifier, $file) {
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
};
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
($requireFile)($fileIdentifier, $file);
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
|
||||
Reference in New Issue
Block a user