]> _ Git - songbook.git/commitdiff
.
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 4 Oct 2022 08:16:09 +0000 (10:16 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 4 Oct 2022 08:16:09 +0000 (10:16 +0200)
16 files changed:
app/Http/Controllers/FrontController.php
app/Models/Collection.php
app/Models/Song.php
config/session.php
dockerterminal.bat
resources/css/app.sass
resources/js/mmenu.js
resources/js/player.js
resources/views/collection.blade.php
resources/views/header.blade.php
resources/views/layout.blade.php
resources/views/login.blade.php [new file with mode: 0644]
resources/views/menu.blade.php
resources/views/song.blade.php
resources/views/welcome.blade.php
routes/web.php

index ba72d9d871bace22835b21956801be28c47a36ad..362a95254d32cd89c123f0eb8b042933aa73e8b3 100644 (file)
@@ -6,6 +6,7 @@ use App\Models\Collection;
 use App\Models\CollectionList;
 use App\Models\Song;
 use Cubist\Backpack\Http\Controllers\CubistPWAController;
+use Illuminate\Support\Facades\Session;
 
 
 class FrontController extends Controller
@@ -18,14 +19,35 @@ class FrontController extends Controller
     public function collection($name)
     {
         $collection = Collection::where('slug', $name)->first();
-
         if (null === $collection) {
             return self::defaultCollection();
         }
+        if ($p = $this->checkPassword($collection)) {
+            return $p;
+        }
         $lists = CollectionList::where('collection', $collection->id)->get();
         $songs = $this->_getSongsOfCollection($collection->id, $lists);
 
-        return view('collection', ['songs' => $songs, 'collection' => $collection, 'collection_songs' => $songs, 'collection_lists' => $lists]);
+        return view('collection', ['menu' => true, 'songs' => $songs, 'collection' => $collection, 'collection_songs' => $songs, 'collection_lists' => $lists]);
+    }
+
+    public function checkPassword(Collection $collection)
+    {
+        if (!$collection->password) {
+            return false;
+        }
+        $error = false;
+        if (request()->has('password')) {
+            if (request('password') === $collection->password) {
+                Session::put('loggedin-' . $collection->id, '1');
+            } else {
+                $error = true;
+            }
+        }
+        if (Session::get('loggedin-' . $collection->id, '0') == '1') {
+            return false;
+        }
+        return view('login', ['menu' => false, 'collection' => $collection, 'error' => $error]);
     }
 
     public function song($collection, $song)
@@ -38,8 +60,11 @@ class FrontController extends Controller
         if (null === $song) {
             abort(404);
         }
+        if ($p = $this->checkPassword($collection)) {
+            return $p;
+        }
         $lists = CollectionList::where('collection', $collection->id)->get();
-        return view('song', ['song' => $song, 'collection' => $collection, 'collection_songs' => $this->_getSongsOfCollection($collection->id, $lists), 'collection_lists' => $lists]);
+        return view('song', ['menu' => true, 'song' => $song, 'collection' => $collection, 'collection_songs' => $this->_getSongsOfCollection($collection->id, $lists), 'collection_lists' => $lists]);
     }
 
     protected function _getSongsOfCollection($id, $lists)
index 1b2b1500cee5534c444c134e173a068e9f57f0c0..7af371a998b30704791648beef4129af0d226612 100644 (file)
@@ -3,10 +3,12 @@
 namespace App\Models;
 
 use Cubist\Backpack\Http\Controllers\CubistPWAController;
+use Cubist\Backpack\Magic\Fields\Checkbox;
 use Cubist\Backpack\Magic\Fields\Color;
 use Cubist\Backpack\Magic\Fields\Images;
 use Cubist\Backpack\Magic\Fields\Slug;
 use Cubist\Backpack\Magic\Fields\Table;
+use Cubist\Backpack\Magic\Fields\Text;
 use Cubist\Backpack\Magic\Models\CubistMagicAbstractModel;
 use Spatie\MediaLibrary\MediaCollections\Models\Media;
 
@@ -17,7 +19,8 @@ class Collection extends CubistMagicAbstractModel
         'singular' => 'collection',
         'plural' => 'collections'];
 
-    public function setFields()
+
+    public function setfields()
     {
         parent::setFields();
         $this->addField('name', 'Text', 'Name', ['column' => true]);
@@ -26,6 +29,9 @@ class Collection extends CubistMagicAbstractModel
         $this->addField('icon', Images::class, 'Icône');
         $this->addField('theme_color', Color::class, 'Couleur d\'accentuation');
         $this->addField('splashscreen_color', Color::class, 'Couleur de fond du splashscreen');
+        $this->addField('password', Text::class, 'Mot de passe', ['hint' => 'Laisser vide pour désactiver']);
+        $this->addField('transpose', Checkbox::class, 'Activer la transposition', ['default' => true, 'database_default' => true]);
+        $this->addField('download_assets', Checkbox::class, 'Activer le téléchargement', ['default' => false, 'database_default' => false]);
     }
 
     public function registerMediaConversions(Media $media = null): void
index bffb0c47ef1192cf3a7074fe0bb8a747818887be..40ac55437e9b27fe3b3f56123e0fd1c73e58ea02 100644 (file)
@@ -10,6 +10,9 @@ use App\Jobs\DownloadAudioTracks;
 use App\SubForm\AudioTrack;
 use App\SubForm\SongPortion;
 use Cubist\Backpack\Magic\Fields\BunchOfFieldsMultiple;
+use Cubist\Backpack\Magic\Fields\Checkbox;
+use Cubist\Backpack\Magic\Fields\Files;
+use Cubist\Backpack\Magic\Fields\SelectFromArray;
 use Cubist\Backpack\Magic\Fields\SelectFromModel;
 use Cubist\Backpack\Magic\Models\CubistMagicAbstractModel;
 
@@ -36,10 +39,13 @@ class Song extends CubistMagicAbstractModel
         $this->addField('artist', 'Text', 'Artist', ['column' => true]);
         $this->addField('key', Tone::class, 'Key', ['column' => true]);
         $this->addField('mode', Mode::class, 'Mode', ['column' => true]);
+        $this->addField('chorale', Checkbox::class, 'Chorale', ['default' => false, 'database_default' => false]);
         $this->addField('collections', \App\Field\CollectionList::class, 'Collections');
         $this->addField('tempo', Tempo::class, 'Suggested tempo', ['column' => true, 'default' => 80]);
-        $this->addField('lyrics', BunchOfFieldsMultiple::class, 'Song Parts', ['bunch' => SongPortion::class, 'new_label' => 'New song part']);
+        $this->addField('partition', Files::class, 'Partition', ['acceptedFiles' => '*.pdf', 'when' => ['chorale' => 1]]);
+        $this->addField('lyrics_doc', Files::class, 'Paroles', ['acceptedFiles' => '*.doc', 'when' => ['chorale' => 1]]);
         $this->addField('audio', BunchOfFieldsMultiple::class, 'Audio tracks', ['bunch' => AudioTrack::class, 'new_label' => 'New audio track']);
+        $this->addField('lyrics', BunchOfFieldsMultiple::class, 'Song Parts', ['bunch' => SongPortion::class, 'new_label' => 'New song part', 'when' => ['chorale' => 0]]);
 //        $this->addField('youtube', URL::class, 'Youtube link');
 //        $this->addField('spotify', URL::class, 'Spotify link');
 //        $this->addField('credits', 'Textarea', 'Credits');
index 857ebc3eab8caad9ccb8b214dafb8e413cd5de9b..bbc4ab1c5404797070732c04774d0fae48853100 100644 (file)
@@ -31,7 +31,7 @@ return [
     |
     */
 
-    'lifetime' => env('SESSION_LIFETIME', 120),
+    'lifetime' => env('SESSION_LIFETIME', 525600),
 
     'expire_on_close' => false,
 
index 10b6bb7c793a9ab0aa704044e3b3c2044e8a6ae3..9c94b63c04ba1b508e1f59f97678da960cdc26c5 100644 (file)
@@ -1,3 +1,3 @@
 @echo off
 cls
-C:\tools\cygwin\bin\ssh.exe -t root@192.168.13.7 'docker exec -it songbook /bin/bash'
+C:\tools\cygwin\bin\ssh.exe -t root@her2.cubedesigners.com 'docker exec -it songbook /bin/bash'
index 7de1fece3cfbc2f7ab4f913005db744bf0919506..748bac4776454d75fd0c315befb9f95f1322c150 100644 (file)
     font-weight: 700
     src: url('fonts/roboto-condensed-700.woff2') format('woff2')
 
+$slab: 'Roboto Slab', sans-serif
+
 *
     margin: 0
     padding: 0
     box-sizing: border-box
 
 h1, h2, h3, h4, h5, h6
-    font-family: 'Roboto Slab', sans-serif
+    font-family: $slab
     font-weight: 500
 
 a
@@ -317,6 +319,10 @@ header
     right: 0
     z-index: 100
 
+    &.nomenu
+        .placeholder
+            padding: 10px
+
     @media print
         position: absolute
 
@@ -451,5 +457,34 @@ header
     bottom: 0
     left: 0
 
+form
+    .error
+        text-align: center
+        padding: 20px 0 0 0
+        color: #cc0000
+
+    input
+        display: block
+        margin: 25px auto
+        width: 100%
+        max-width: 400px
+        text-align: center
+        border-radius: 5px
+        border: 0
+        padding: 15px
+        font-size: 16px
+        font-weight: 500
+        font-family: $slab
+
+    input[type=password]
+        text-align: left
+        outline-color:  var(--theme-color)
+
+    input[type=submit]
+        background-color: var(--theme-color)
+        color: #fff
+        cursor: pointer
+
+
 @import "../../node_modules/mmenu-light/dist/mmenu-light.css"
 @import "../../node_modules/plyr/dist/plyr.css"
index 13d3a41fb260a224d2ecc85a66226d679884df71..af36d08d67087dcefec020b91c537b81382faa1f 100644 (file)
@@ -4,27 +4,30 @@ import Switch from "weatherstar-switch";
 document.addEventListener("DOMContentLoaded", () => {
 
     var darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
-    const menu = new MmenuLight(document.querySelector("#menu"));
+    if ($('#menu').length > 0) {
+        const menu = new MmenuLight(document.querySelector("#menu"));
 
-    const navigator = menu.navigation({theme: darkMode ? 'dark' : 'light'});
-    const drawer = menu.offcanvas();
 
-    document.querySelector('#menu-icon')
-        .addEventListener('click', (evnt) => {
-            evnt.preventDefault();
-            drawer.open();
-        });
+        const navigator = menu.navigation({theme: darkMode ? 'dark' : 'light'});
+        const drawer = menu.offcanvas();
 
+        document.querySelector('#menu-icon')
+            .addEventListener('click', (evnt) => {
+                evnt.preventDefault();
+                drawer.open();
+            });
 
-    var mc = new Hammer(document.getElementsByTagName('main').item(0), {touchAction: "auto"})
 
-    mc.on('swiperight', function (e) {
-        if (e.distance > 100 && e.overallVelocityX > 0.4) {
-            drawer.open();
-            return false;
-        }
-        return true;
-    });
+        var mc = new Hammer(document.getElementsByTagName('main').item(0), {touchAction: "auto"})
+
+        mc.on('swiperight', function (e) {
+            if (e.distance > 100 && e.overallVelocityX > 0.4) {
+                drawer.open();
+                return false;
+            }
+            return true;
+        });
+    }
 
     $('body').addClass('init');
 });
index 139dd45e873f93fae07099a521dead6b82c8a220..37a9560fbf89ec2a2437ad971fa60b73959ba545 100644 (file)
         $(this).hide();
 
         var audio = window.getOption('audio').toString();
-        var tone = window.getOption('audio_' + audio + '_tone').toString();
+        var t = window.getOption('audio_' + audio + '_tone');
+        if (t === undefined) {
+            t = 0;
+        }
+        var tone = t.toString();
         if (tone === 'undefined') {
             tone = '0';
         }
index f8769d6c08bf90a51543a82e496c609ba71a471a..7987749050cfb233df57e06874a7563e8ba39aea 100644 (file)
@@ -2,7 +2,7 @@
 @php
     $preload=[];
 @endphp
-@section('title', $collection->name.' Songbook')
+@section('title', $collection->name)
 
 @section('content')
     @include('header',['title'=>$collection->name,'subtitle'=>''])
index 6e04ec1647fc82b01c015d1da109f511cb5dbc7c..5a0e5d9a2f1f9715c4ef3f53cbf8f62b1a7f85c7 100644 (file)
@@ -1,16 +1,24 @@
 <div id="header-space">
 
 </div>
-<header>
+<header @if(!$menu)
+            class="nomenu"
+    @endif
+>
     <div class="placeholder">
-        <a href="#" id="menu-icon">
-            <svg viewBox="0 0 100 80" width="40" height="40">
-                <rect fill="currentColor" width="100" height="5"></rect>
-                <rect fill="currentColor" y="30" width="100" height="5"></rect>
-                <rect fill="currentColor" y="60" width="100" height="5"></rect>
-            </svg>
-        </a>
-        <h1>{{$title}}</h1>
+        @if($menu)
+            <a href="#" id="menu-icon">
+                <svg viewBox="0 0 100 80" width="40" height="40">
+                    <rect fill="currentColor" width="100" height="5"></rect>
+                    <rect fill="currentColor" y="30" width="100" height="5"></rect>
+                    <rect fill="currentColor" y="60" width="100" height="5"></rect>
+                </svg>
+            </a>
+            <h1>{{$title}}</h1>
+        @else
+            <h1>{{$title}}</h1>
+        @endif
+
         @if($subtitle)
             <h2>{{$subtitle}}</h2>
         @endif
index 5485d26fdc9cb1bc72aa0527e0b612979d9fabd8..11bf20e8682b8e5a87477d8de9891351998d2f63 100644 (file)
@@ -1,5 +1,5 @@
 @include('menu')
-<!DOCTYPE html>
+    <!DOCTYPE html>
 <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
 <head>
     <meta charset="utf-8">
 <main class="content page" id="page">
     @yield('content')
 </main>
-<nav id="floating">
-    @yield('floating')
-</nav>
-@yield('menu')
+@if($menu)
+    <nav id="floating">
+        @yield('floating')
+    </nav>
+    @yield('menu')
+@endif
 <script>
     // Check that service workers are supported
     if ('serviceWorker' in navigator) {
diff --git a/resources/views/login.blade.php b/resources/views/login.blade.php
new file mode 100644 (file)
index 0000000..9c9fcbb
--- /dev/null
@@ -0,0 +1,17 @@
+@extends('layout')
+@php
+    $preload=[];
+@endphp
+@section('title', $collection->name)
+
+@section('content')
+    @include('header',['title'=>$collection->name,'subtitle'=>''])
+    <form action="" method="post">
+        @if($error)
+            <p class="error">Mot de passe erroné</p>
+        @endif
+        @csrf
+        <input type="password" name="password" placeholder="Mot de passe">
+        <input type="submit" value="Connexion">
+    </form>
+@endsection
index ec7bf6ee75f93566eb5f2d5eabf0b47411bd00b1..f05a5ef3a0dccc13a2c90910da304e917afa6873 100644 (file)
             <li><a href="/{{$collection->slug}}">📖 {{__('Home')}}</a></li>
             <li><span>🎶 {{__('Songs')}}</span>
                 <ul>
-                    @foreach($collection_songs as $csong)
-                        @if(!in_array($collection->id, $csong->collections))
-                            @continue
-                        @endif
-                        @include('menu_song')
-                    @endforeach
-                    @foreach($collection_lists as $list)
-                        <li><span>📒 {{$list->name}}</span>
-                            <ul>
-                                @foreach($collection_songs as $csong)
-                                    @if(!in_array($collection->id.'_'.$list->id, $csong->collections))
-                                        @continue
-                                    @endif
-                                    @include('menu_song')
-                                @endforeach
-                            </ul>
-                        </li>
-                    @endforeach
+                    @if(isset($collection_songs))
+                        @foreach($collection_songs as $csong)
+                            @if(!in_array($collection->id, $csong->collections))
+                                @continue
+                            @endif
+                            @include('menu_song')
+                        @endforeach
+                    @endif
+                    @if(isset($collection_lists))
+                        @foreach($collection_lists as $list)
+                            <li><span>📒 {{$list->name}}</span>
+                                <ul>
+                                    @foreach($collection_songs as $csong)
+                                        @if(!in_array($collection->id.'_'.$list->id, $csong->collections))
+                                            @continue
+                                        @endif
+                                        @include('menu_song')
+                                    @endforeach
+                                </ul>
+                            </li>
+                        @endforeach
+                    @endif
                 </ul>
             </li>
             @if(isset($song))
 
                 @if($song->hasChords())
-                    <li><a href="#" class="noaction">🎤 {{__('Show lyrics')}} <input type="checkbox" class="checkbox-switch"
-                                                                          name="show_lyrics_{{$song->id}}"
-                                                                          data-default="1"></a></li>
-                    <li><a href="#" class="noaction">🎼 {{__('Show chords')}} <input type="checkbox" class="checkbox-switch"
-                                                                          name="show_chords_{{$song->id}}"
-                                                                          data-default="1"></a></li>
+                    <li><a href="#" class="noaction">🎤 {{__('Show lyrics')}} <input type="checkbox"
+                                                                                    class="checkbox-switch"
+                                                                                    name="show_lyrics_{{$song->id}}"
+                                                                                    data-default="1"></a></li>
+                    <li><a href="#" class="noaction">🎼 {{__('Show chords')}} <input type="checkbox"
+                                                                                    class="checkbox-switch"
+                                                                                    name="show_chords_{{$song->id}}"
+                                                                                    data-default="1"></a></li>
                     @if($song->hasSimpleChords())
                         <li><a href="#" class="noaction">🐣 {{__('Show simple chords')}} <input type="checkbox"
-                                                                                     class="checkbox-switch"
-                                                                                     name="show_simplechords_{{$song->id}}"
-                                                                                     data-default="0"></a></li>
+                                                                                               class="checkbox-switch"
+                                                                                               name="show_simplechords_{{$song->id}}"
+                                                                                               data-default="0"></a>
+                        </li>
                     @endif
-                    <li><a href="#" class="clickselect">↕️ {{__('Key')}} <select data-name="tone" name="tone_{{$song->id}}">
+                    <li><a href="#" class="clickselect">↕️ {{__('Key')}} <select data-name="tone"
+                                                                                 name="tone_{{$song->id}}">
                                 @for($i=-5;$i<=6;$i++)
                                     <option value="{{$i}}"
                                             @if($i===0) selected @endif>{{$tones[(12+$song->key+$i)%12].$song->mode}} @if($i>0)
                             </select><span></span></a></li>
                 @else
                     <li class="hidden"><a href="#" class="noaction">{{__('Show chords')}} <input type="checkbox"
-                                                                                       class="checkbox-switch"
-                                                                                       name="show_chords_{{$song->id}}"
-                                                                                       data-default="0"></a></li>
+                                                                                                 class="checkbox-switch"
+                                                                                                 name="show_chords_{{$song->id}}"
+                                                                                                 data-default="0"></a>
+                    </li>
                     <li class="hidden"><a href="#" class="noaction">{{__('Show lyrics')}} <input type="checkbox"
-                                                                                       class="checkbox-switch"
-                                                                                       name="show_lyrics_{{$song->id}}"
-                                                                                       data-default="1"></a></li>
+                                                                                                 class="checkbox-switch"
+                                                                                                 name="show_lyrics_{{$song->id}}"
+                                                                                                 data-default="1"></a>
+                    </li>
                 @endif
 
                 <li><a href="#" class="clickselect">🔠 {{__('Lyrics text size')}} <select data-name="size"
-                                                                               name="size_{{$song->id}}">
+                                                                                         name="size_{{$song->id}}">
                             @foreach($fontSizes as $s)
                                 <option value="{{$s}}" @if($s===1) selected @endif>{!! round($s*100) !!}%</option>
                             @endforeach
@@ -76,7 +86,7 @@
 
                 @if(count($song->getAudioTracks())>0)
                     <li><a href="#" class="clickselect">💿 {{__('Audio track')}} <select data-name="audio"
-                                                                              name="audio_{{$song->id}}">
+                                                                                        name="audio_{{$song->id}}">
                                 @foreach($song->getAudioTracks() as $i=>$track)
                                     <option value="{{$i}}" data-url="{{$track['url']}}">{{$track['name']}}</option>
                                 @endforeach
index 8096321e637baaf5645ff33127640629ee645420..0dc28529b5f5d0aa668b72961880268732eeb855 100644 (file)
@@ -4,7 +4,7 @@
 @endphp
 
 @extends('layout')
-@section('title', $song->title.' - '.$song->artist.' - '. $collection->name.' Songbook')
+@section('title', $song->title.' - '.$song->artist.' - '. $collection->name)
 @section('content')
     @include('header',['title'=>$song->title,'subtitle'=>$song->artist])
     <article class="song" data-tone="{{$song->key}}" data-mode="{{$song->mode}}">
index 4a5c52c7caca43cbbc46f159dd36460ce309353c..f17b97b1684679b21e67c2c090848f834ec484ae 100644 (file)
@@ -4,7 +4,7 @@
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1">
 
-        <title>{{$collection->name}} Songbook</title>
+        <title>{{$collection->name}}</title>
 
         <!-- Fonts -->
         <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
index 55c4e01786896790a3556372a8410795f6f8b9e4..16ce1df6a0a20e838b5585486a69284dcd4de44d 100644 (file)
@@ -14,9 +14,9 @@ use Illuminate\Support\Facades\Route;
 |
 */
 
-Route::get('/', function(){
+Route::get('/', function () {
     return FrontController::defaultCollection();
 });
 Route::get('{collection}.webmanifest', [FrontController::class, 'manifest']);
-Route::get('{collection}', [FrontController::class, 'collection']);
-Route::get('{collection}/{song}.html', [FrontController::class, 'song']);
+Route::any('{collection}', [FrontController::class, 'collection']);
+Route::any('{collection}/{song}.html', [FrontController::class, 'song']);