Просмотр исходного кода

added more features to untube search

sleepytaco 3 лет назад
Родитель
Сommit
6598b41c52

+ 3 - 1
apps/main/models.py

@@ -981,9 +981,11 @@ class PlaylistManager(models.Manager):
                 new_playlist_duration_in_seconds -= video.duration_in_seconds
 
         playlist.video_count = new_playlist_video_count
+        if new_playlist_video_count == 0:
+            playlist.thumbnail_url = ""
         playlist.playlist_duration_in_seconds = new_playlist_duration_in_seconds
         playlist.playlist_duration = getHumanizedTimeString(new_playlist_duration_in_seconds)
-        playlist.save(update_fields=['video_count', 'playlist_duration', 'playlist_duration_in_seconds'])
+        playlist.save(update_fields=['video_count', 'playlist_duration', 'playlist_duration_in_seconds', 'thumbnail_url'])
         # time.sleep(2)
 
         playlist_items = playlist.playlist_items.select_related('video').order_by("video_position")

+ 14 - 14
apps/main/templates/all_playlists.html

@@ -4,7 +4,7 @@
 
 
         <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 mb-3">
-            <h1 class="h2"><span style="border-bottom: 3px #e24949 dashed;">{{ playlist_type_display|title }}</span> <span class="badge bg-primary rounded-pill">{{ playlists.count }}</span></h1>
+            <h1 class="h2"><span style="border-bottom: 3px #e24949 dashed;">{{ library_type_display|title }}</span> <span class="badge bg-primary rounded-pill">{{ playlists.count }}</span></h1>
 
             {% if playlists %}
             <div class="btn-toolbar mb-2 mb-md-0">
@@ -19,9 +19,9 @@
                     Sort By
                   </button>
                   <ul class="dropdown-menu">
-                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' playlist_type 'playlist-duration-in-seconds' %}" hx-trigger="click" hx-target="#search-results">Duration</a></li>
-                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' playlist_type 'video-count' %}" hx-trigger="click" hx-target="#search-results"># Videos</a></li>
-                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' playlist_type 'recently-accessed' %}" hx-trigger="click" hx-target="#search-results">Recently Accessed</a></li>
+                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' library_type 'playlist-duration-in-seconds' %}" hx-trigger="click" hx-target="#search-results">Duration</a></li>
+                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' library_type 'video-count' %}" hx-trigger="click" hx-target="#search-results"># Videos</a></li>
+                    <li class="dropdown-item"><a hx-get="{% url 'order_playlists_by' library_type 'recently-accessed' %}" hx-trigger="click" hx-target="#search-results">Recently Accessed</a></li>
                   </ul>
                 </div>
 
@@ -33,14 +33,14 @@
         {% if playlists %}
             <input   class="form-control border border-secondary" type="text"
                    name="search" placeholder="Begin to search playlists..."
-                   hx-post="{% url 'search_playlists' playlist_type %}"
+                   hx-post="{% url 'search_playlists' library_type %}"
                    hx-trigger="keyup changed delay:700ms"
                    hx-target="#search-results"
                    hx-indicator=".htmx-indicator"
                     aria-describedby="searchHelp">
-            <div id="searchHelp" class="form-text">For a more extensive playlist search, click the search icon in the nav bar.</div>
-          <br>
+            <div id="searchHelp" class="form-text">For a more extensive playlist search, <a href="{% url 'search' %}?mode=playlists&type={{ library_type }}">click here</a>.</div>
 
+            <br>
 
         <div id="search-results" class="row row-cols-1 row-cols-md-4 g-4">
             {% include 'intercooler/playlists.html' with show_controls=True %}
@@ -52,24 +52,24 @@
                     Nothing here!
                 </div>
                 <div class="d-flex justify-content-center h5">
-                    {% if playlist_type == "watching" %}
+                    {% if library_type == "watching" %}
                         You can mark a playlist as watching by heading over to the playlist and marking it from the dropdown.
-                    {% elif playlist_type == "all" %}
+                    {% elif library_type == "all" %}
                         There's no playlists in your UnTube right now.
-                    {% elif playlist_type == "imported" %}
+                    {% elif library_type == "imported" %}
                         To import public playlists into your UnTube collection you can head over to <a href="{% url 'manage_playlists' %}" class="btn btn-sm btn-primary ms-2">Manage</a>
-                    {% elif playlist_type == "plan-to-watch" %}
+                    {% elif library_type == "plan-to-watch" %}
                         You can mark a playlist as plan to watch by heading over to the playlist and marking it from the dropdown.
-                    {% elif playlist_type == "favorites" %}
+                    {% elif library_type == "favorites" %}
                         You can mark a playlist as favorite by heading over to the playlist page and pressing the star icon.
-                    {% elif playlist_type == "user-owned" %}
+                    {% elif library_type == "user-owned" %}
                         {% if user.profile.imported_yt_playlists %}
                             Looks like you have no playlists on YouTube.
                         {% else %}
                             You can always head over to your <a href="{% url 'profile' %}" class="btn btn-sm btn-primary ms-2 me-2">Profile</a> to import all of your public/private YouTube playlists.
                         {% endif %}
                     {% else %}
-                        {{ playlist_type }}
+                        {{ library_type }}
                     {% endif %}
                 </div>
             </div>

+ 1 - 1
apps/main/templates/all_playlists_with_tag.html

@@ -5,7 +5,7 @@
     <div id="search-results">
 
         <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 mb-3">
-            <h1 class="h2"> <span style="border-bottom: 3px #e24949 dashed;" class="pt-3">Playlists Tagged as</span> <kbd>{{ tag.name }}</kbd> <span class="badge bg-warning rounded-pill">{{ playlists.count }}</span></h1>
+            <h1 class="h2"> <span style="border-bottom: 3px #e24949 dashed;" class="pt-3">Playlists Tagged as</span> <kbd>{{ tag.name }}</kbd> <span class="badge bg-warning rounded-pill">{{ playlists.count }}</span> <a href="{% url 'search' %}?tag={{ tag.name }}"><i class="fas fa-search" style="color: black"></i></a></h1>
 
         </div>
 

+ 2 - 2
apps/main/templates/favorites.html

@@ -6,7 +6,7 @@
         <h1 class="h2">Favorite Playlists
             <span class="badge bg-primary rounded-pill">{{ playlists.count|default:"0" }}</span>
             {% if playlists %}
-                <a href="{% url 'all_playlists' 'favorites' %}" style="text-decoration: none; color: black"><i class="fas fa-search"></i></a>
+                <a href="{% url 'search' %}?mode=playlists&type=favorites" style="text-decoration: none; color: black"><i class="fas fa-search"></i></a>
             {% endif %}
         </h1>
     </div>
@@ -28,7 +28,7 @@
         <h1 class="h2">Favorite Videos
             <span class="badge bg-primary rounded-pill">{{ videos.count }}</span>
             {% if videos %}
-                <a href="{% url 'search_UnTube' %}" style="text-decoration: none; color: black"><i class="fas fa-search"></i></a>
+                <a href="{% url 'search' %}?mode=videos&type=favorite" style="text-decoration: none; color: black"><i class="fas fa-search"></i></a>
             {% endif %}
         </h1>
     </div>

+ 7 - 7
apps/main/templates/home.html

@@ -81,13 +81,13 @@
                 <div class="card card-cover h-100 overflow-hidden text-white {% if not user.profile.enable_gradient_bg  %}gradient-bg-3{% else %}bg-dark{% endif %} rounded-5 shadow-lg" style="">
                     <div class="d-flex flex-column h-100 p-5 pb-3 text-white text-shadow-1">
                         <h2 class="pt-5 mt-5 mb-4 display-6 lh-1 fw-bold">
-                            <a href="{% url 'all_playlists' 'all' %}" class="stretched-link" style="text-decoration: none; color: #fafafa">
+                            <a href="{% url 'library' 'all' %}" class="stretched-link" style="text-decoration: none; color: #fafafa">
                                 All Playlists</a>
                         </h2>
                         <ul class="d-flex list-unstyled mt-auto">
                             <li class="me-auto">
                                 <h3>
-                                    <i class="fas fa-mountain fa-lg" style="color: #e26f94"></i>
+                                    <i class="fas fa-mountain fa-lg" style="color: #a9e26f"></i>
                                 </h3>
                             </li>
                         </ul>
@@ -137,14 +137,14 @@
                 <div class="card card-cover h-100 overflow-hidden text-white {% if not user.profile.enable_gradient_bg  %}gradient-bg-3{% else %}bg-dark{% endif %} rounded-5 shadow-lg" style="">
                     <div class="d-flex flex-column h-100 p-5 pb-3 text-white text-shadow-1">
                         <h2 class="pt-5 mt-5 mb-4 display-6 lh-1 fw-bold">
-                            <a href="https://www.youtube.com/" target="_blank" class="stretched-link" style="text-decoration: none; color: #fafafa">
-                                Open YouTube
+                            <a href="{% url 'library' 'plan-to-watch' %}" class="stretched-link" style="text-decoration: none; color: #fafafa">
+                                Planned to Watch
                             </a>
                         </h2>
                         <ul class="d-flex list-unstyled mt-auto">
                             <li class="me-auto">
                                 <h3>
-                                    <i class="fab fa-youtube fa-lg" style="color: #db477b"></i>
+                                    <i class="fas fa-sad-cry fa-lg" style="color: #db477b"></i>
                                 </h3>
                             </li>
                         </ul>
@@ -217,7 +217,7 @@
             <div class="col">
                 <div class="card bg-transparent border border-0 text-black">
                     <div class="card-body">
-                        <h3><span style="border-bottom: 3px #a35a5a dashed;">Most viewed playlists</span> <a href="{% url 'all_playlists' 'all' %}" class="pt-1"><i class="fas fa-binoculars"></i> </a></h3>
+                        <h3><span style="border-bottom: 3px #a35a5a dashed;">Most viewed playlists</span> <a href="{% url 'library' 'all' %}" class="pt-1"><i class="fas fa-binoculars"></i> </a></h3>
                         {% if user_playlists %}
                             <div class="row row-cols-1 row-cols-md-3 g-4 text-dark mt-0">
                                 {% include 'intercooler/playlists.html' with playlists=user_playlists|slice:"0:3" watching=False %}
@@ -244,7 +244,7 @@
                 {% if watching.count > 5 %}
 
                     <h3 class="ms-2 me-1">
-                        <a href="{% url 'all_playlists' 'watching' %}" style="text-decoration: none; color: #4675d2">
+                        <a href="{% url 'library' 'watching' %}" style="text-decoration: none; color: #4675d2">
                             <i class="fas fa-search" style="color: #4675d2"></i>
                         </a>
                     </h3>

+ 1 - 1
apps/main/templates/intercooler/playlists.html

@@ -23,7 +23,7 @@
         <div class="col">
             <div class="card overflow-auto" style="background-color: {{ bg_color|default:"#4790c7" }};">
                 <a href="{% url 'playlist' playlist.playlist_id %}" style="text-decoration: none; color: black">
-                    <img  class="bd-placeholder-img card-img-top" src="{{ playlist.thumbnail_url }}" style="max-width:100%; height: 200px;   object-fit: cover;" alt="{{ playlist.name }} thumbnail">
+                    <img  class="bd-placeholder-img card-img-top" src="{% if playlist.thumbnail_url %}{{ playlist.thumbnail_url }}{% else %}https://i.ytimg.com/vi/9219YrnwDXE/maxresdefault.jpg{% endif %}" style="max-width:100%; height: 200px;   object-fit: cover;" alt="{{ playlist.name }} thumbnail">
                 </a>
                 <div class="card-body">
                     <h5 class="card-title"><a href="{% url 'playlist' playlist.playlist_id %}" style="text-decoration: none; color: black">{{ playlist.name }}</a></h5>

+ 21 - 8
apps/main/templates/playlists_home.html → apps/main/templates/library.html

@@ -3,7 +3,7 @@
 
 <div class="row row-cols-1 row-cols-md-3 g-4" >
     <div class="col">
-        <a href="{% url 'all_playlists' 'all' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'all' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #64381a;">
             <div class="card-body">
                 <h4 class="card-title">All Playlists</h4>
@@ -13,7 +13,7 @@
         </a>
     </div>
     <div class="col">
-        <a href="{% url 'all_playlists' 'user-owned' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'user-owned' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #1A4464;">
             <div class="card-body">
                 <h4 class="card-title">Your YouTube Playlists</h4>
@@ -24,7 +24,7 @@
     </div>
 
     <div class="col">
-        <a href="{% url 'all_playlists' 'imported' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'imported' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #1a645e;">
             <div class="card-body">
                 <h4 class="card-title">Imported Playlists</h4>
@@ -34,7 +34,7 @@
         </a>
     </div>
     <div class="col">
-        <a href="{% url 'all_playlists' 'favorites' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'favorites' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #aa8c2e;">
             <div class="card-body">
                 <h4 class="card-title">Favorite Playlists</h4>
@@ -44,7 +44,7 @@
         </a>
     </div>
     <div class="col">
-        <a href="{% url 'all_playlists' 'watching' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'watching' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #541a64;">
             <div class="card-body">
                 <h4 class="card-title">Watching Playlists</h4>
@@ -54,7 +54,7 @@
         </a>
     </div>
     <div class="col">
-        <a href="{% url 'all_playlists' 'plan-to-watch' %}" class="text-decoration-none text-white">
+        <a href="{% url 'library' 'plan-to-watch' %}" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #641a29;">
             <div class="card-body">
                 <h4 class="card-title">Plan to Watch</h4>
@@ -74,6 +74,18 @@
         </a>
     </div>
 
+    <div class="col">
+        <a href="#" class="text-decoration-none text-white">
+        <div class="card h-100" style="background-color: #7f8675;">
+            <div class="card-body">
+                <h5 class="card-title">Unavailable YouTube Videos</h5>
+                <p class="card-text">List of videos in your collection that went unavailable on YouTube. Note that all details except the video title will have been deleted once a video goes unavailable on YouTube.</p>
+            </div>
+        </div>
+        </a>
+    </div>
+
+    <!--
     <div class="col">
         <a href="#" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #969291;">
@@ -84,6 +96,7 @@
         </div>
         </a>
     </div>
+    -->
     <div class="col">
         <a href="#" class="text-decoration-none text-white">
 
@@ -91,7 +104,7 @@
             <div class="card-body">
                 <h5 class="card-title">Open a Random Playlist</h5>
                 <p class="card-text mt-4">
-                    <form action="{% url 'all_playlists' 'random' %}" method="post">
+                    <form action="{% url 'library' 'random' %}" method="post">
                         {% csrf_token %}
                         <select onchange="this.form.submit()" class="form-select w-50 bg-success text-white" name="playlistsType">
                               <option value="From" selected>From</option>
@@ -134,7 +147,7 @@
             <div class="card-footer">
                 <div class="d-flex justify-content-center">
                     <h3>
-                        <a href="" class="btn btn-success">Filter Playlists by Tags</a>
+                        <a href="{% url 'search' %}" class="btn btn-success">Filter Playlists by Tags</a>
                         <a href="" class="btn btn-danger">Edit Tags</a>
                     </h3>
                 </div>

+ 18 - 0
apps/main/templates/view_video.html

@@ -11,17 +11,34 @@
 
         {% else %}
 
+            <div class="alert alert-dark alert-dismissible fade show" role="alert" id="user-label-alert"  style="display:none;">
+                <form method="post" action="{% url 'add_video_user_label' video.video_id %}" class="d-flex justify-content-center">
+                    {% csrf_token %}
+                    <span class="mt-2 me-1">Enter an optional label to identify this video with:</span>
+                    <input class="form-control w-25 me-2" type="text" placeholder="Enter here" name="user_label" value="{{ video.user_label }}" aria-label="user label">
+                    <button type="submit" class="btn btn-primary">Save</button>
 
+                </form>
+                              <button type="button" class="btn-close mt-2 me-2" onclick='document.getElementById("user-label-alert").style.display = "none";' aria-label="Close"></button>
+
+            </div>
             <div class="card text-white bg-dark" style="max-width: 100%;">
                 <div class="row g-0">
                     <div class="col-md-4 p-3">
                         <img  class="img-fluid rounded-3" src="{{ video.thumbnail_url }}" style="max-width:100%; height: auto;   object-fit: cover;">
+                        <span class="d-flex justify-content-center">
+                        <a type="submit" onclick="window.open('{{ video.thumbnail_url }}')" class="btn btn-primary mt-3"><i class="fas fa-image fa-lg me-2"></i> Download Thumbnail</a>
+                            </span>
                     </div>
                     <div class="col-md-8">
                         <div class="card-body">
                             <div class="row d-flex justify-content-between">
                                 <h2 class="card-title text-white col-10">
                                     <a href="https://www.youtube.com/watch?v={{ video.video_id }}" target="_blank" style="color: white; text-decoration: none">{{ video.name }}</a>
+                                    <button class="btn btn-light btn-sm ms-2" onclick='document.getElementById("user-label-alert").style.display = "block";'>
+                                            <i class="fas fa-pencil-alt" aria-hidden="true"></i>
+                                        </button>
+
                                     <br><small class="h4">{% if video.user_label %}a.k.a <span style="border-bottom: 3px #ffffff dashed;"> {{ video.user_label }}</span>{% endif %}</small>
                                 </h2>
                                 <h4 class="col d-flex justify-content-end">
@@ -29,6 +46,7 @@
 
                                     </span>
                                     <span id="">
+
                                         <input class="form-control me-1 visually-hidden" id="video-{{ video.video_id }}" value="https://www.youtube.com/watch?v={{ video.video_id }}">
                                         <button class="copy-btn btn btn-success  me-1" data-clipboard-target="#video-{{ video.video_id }}">
                                             <i class="far fa-copy" aria-hidden="true"></i>

+ 2 - 2
apps/main/urls.py

@@ -7,15 +7,16 @@ urlpatterns = [
     ### STUFF RELATED TO WHOLE SITE
     path("home/", views.home, name='home'),
     path("favorites", views.favorites, name="favorites"),
+    path("library/<slug:library_type>", views.library, name='library'),
 
     ### STUFF RELATED TO INDIVIDUAL VIDEOS
     path("video/<slug:video_id>", views.view_video, name='video'),
     path("video/<slug:video_id>/video-details/favorite", views.mark_video_favortie, name='mark_video_favorite'),
     path("video/<slug:video_id>/notes", views.video_notes, name='video_notes'),
     path("video/<slug:video_id>/get-video-completion-times", views.video_completion_times, name="video_completion_times"),
+    path("video/<slug:video_id>/add-user-label", views.add_video_user_label, name='add_video_user_label'),
 
     ### STUFF RELATED TO VIDEO(S) INSIDE PLAYLISTS
-    path("videos/<slug:videos_type>", views.all_videos, name='all_videos'),
 
     ### STUFF RELATED TO ONE PLAYLIST
     path("playlist/<slug:playlist_id>", views.view_playlist, name='playlist'),
@@ -45,7 +46,6 @@ urlpatterns = [
          name="playlist_completion_times"),
 
     ### STUFF RELATED TO PLAYLISTS IN BULK
-    path("playlists/<slug:playlist_type>", views.all_playlists, name='all_playlists'),
     path("playlists/<slug:playlist_type>/order-by/<slug:order_by>", views.order_playlists_by, name='order_playlists_by'),
     path("playlists/tag/<str:tag>", views.tagged_playlists, name='tagged_playlists'),
 

+ 47 - 82
apps/main/views.py

@@ -51,8 +51,10 @@ def home(request):
         if user_profile.profile.imported_yt_playlists:
             user_profile.profile.show_import_page = False  # after user imports all their YT playlists no need to show_import_page again
             user_profile.profile.save(update_fields=['show_import_page'])
-            imported_playlists_count = request.user.playlists.filter(Q(is_user_owned=True) & Q(is_in_db=True)).exclude(playlist_id="LL").count()
-            return render(request, "home.html", {"import_successful": True, "imported_playlists_count": imported_playlists_count})
+            imported_playlists_count = request.user.playlists.filter(Q(is_user_owned=True) & Q(is_in_db=True)).exclude(
+                playlist_id="LL").count()
+            return render(request, "home.html",
+                          {"import_successful": True, "imported_playlists_count": imported_playlists_count})
 
         return render(request, "import_in_progress.html")
     ##################################
@@ -192,33 +194,33 @@ def tagged_playlists(request, tag):
 
 
 @login_required
-def all_playlists(request, playlist_type):
+def library(request, library_type):
     """
     Possible playlist types for marked_as attribute: (saved in database like this)
     "none", "watching", "plan-to-watch"
     """
-    playlist_type = playlist_type.lower()
+    library_type = library_type.lower()
     watching = False
-    if playlist_type == "" or playlist_type == "all":
+    if library_type == "" or library_type == "all":
         playlists = request.user.playlists.all().filter(is_in_db=True)
-        playlist_type_display = "All Playlists"
-    elif playlist_type == "user-owned":  # YT playlists owned by user
+        library_type_display = "All Playlists"
+    elif library_type == "user-owned":  # YT playlists owned by user
         playlists = request.user.playlists.all().filter(Q(is_user_owned=True) & Q(is_in_db=True))
-        playlist_type_display = "Your YouTube Playlists"
-    elif playlist_type == "imported":  # YT playlists (public) owned by others
+        library_type_display = "Your YouTube Playlists"
+    elif library_type == "imported":  # YT playlists (public) owned by others
         playlists = request.user.playlists.all().filter(Q(is_user_owned=False) & Q(is_in_db=True))
-        playlist_type_display = "Imported playlists"
-    elif playlist_type == "favorites":  # YT playlists (public) owned by others
+        library_type_display = "Imported playlists"
+    elif library_type == "favorites":  # YT playlists (public) owned by others
         playlists = request.user.playlists.all().filter(Q(is_favorite=True) & Q(is_in_db=True))
-        playlist_type_display = "Favorites"
-    elif playlist_type.lower() in ["watching", "plan-to-watch"]:
-        playlists = request.user.playlists.filter(Q(marked_as=playlist_type.lower()) & Q(is_in_db=True))
-        playlist_type_display = playlist_type.lower().replace("-", " ")
-        if playlist_type.lower() == "watching":
+        library_type_display = "Favorites"
+    elif library_type.lower() in ["watching", "plan-to-watch"]:
+        playlists = request.user.playlists.filter(Q(marked_as=library_type.lower()) & Q(is_in_db=True))
+        library_type_display = library_type.lower().replace("-", " ")
+        if library_type.lower() == "watching":
             watching = True
-    elif playlist_type.lower() == "home":  # displays cards of all playlist types
-        return render(request, 'playlists_home.html')
-    elif playlist_type.lower() == "random":  # randomize playlist
+    elif library_type.lower() == "home":  # displays cards of all playlist types
+        return render(request, 'library.html')
+    elif library_type.lower() == "random":  # randomize playlist
         if request.method == "POST":
             playlists_type = request.POST["playlistsType"]
             if playlists_type == "All":
@@ -237,56 +239,16 @@ def all_playlists(request, playlist_type):
                 return redirect('/playlists/home')
             random_playlist = random.choice(playlists)
             return redirect(f'/playlist/{random_playlist.playlist_id}')
-        return render(request, 'playlists_home.html')
+        return render(request, 'library.html')
     else:
         return redirect('home')
 
     return render(request, 'all_playlists.html', {"playlists": playlists,
-                                                  "playlist_type": playlist_type,
-                                                  "playlist_type_display": playlist_type_display,
+                                                  "library_type": library_type,
+                                                  "library_type_display": library_type_display,
                                                   "watching": watching})
 
 
-@login_required
-def all_videos(request, videos_type):
-    """
-    To implement this need to redesign the database
-    Currently videos -> playlist -> user.profile
-
-    Need to do
-    user.profile <- videos <- playlistItem -> playlist
-    many ways actually
-    """
-    videos_type = videos_type.lower()
-
-    if videos_type == "" or videos_type == "all":
-        playlists = request.user.playlists.all().filter(is_in_db=True)
-        videos_type_display = "All Videos"
-    elif videos_type == "user-owned":  # YT playlists owned by user
-        playlists = request.user.playlists.all().filter(Q(is_user_owned=True) & Q(is_in_db=True))
-        videos_type_display = "All Videos in your YouTube Playlists"
-    elif videos_type == "imported":  # YT playlists (public) owned by others
-        playlists = request.user.playlists.all().filter(Q(is_user_owned=False) & Q(is_in_db=True))
-        videos_type_display = "Imported YouTube Playlists Videos"
-    elif videos_type == "favorites":  # YT playlists (public) owned by others
-        playlists = request.user.playlists.all().filter(Q(is_favorite=True) & Q(is_in_db=True))
-        videos_type_display = "Favorite Videos"
-    elif videos_type == "watched":  # YT playlists (public) owned by others
-        playlists = request.user.playlists.all().filter(Q(is_favorite=True) & Q(is_in_db=True))
-        videos_type_display = "Watched Videos"
-    elif videos_type == 'hidden-videos':  # YT playlists (public) owned by others
-        playlists = request.user.playlists.all().filter(Q(is_favorite=True) & Q(is_in_db=True))
-        videos_type_display = "Hidden Videos"
-    elif videos_type.lower() == "home":  # displays cards of all playlist types
-        return render(request, 'videos_home.html')
-    else:
-        return redirect('home')
-
-    return render(request, 'all_playlists.html', {"playlists": playlists,
-                                                  "videos_type": videos_type,
-                                                  "videos_type_display": videos_type_display})
-
-
 @login_required
 def order_playlist_by(request, playlist_id, order_by):
     playlist = request.user.playlists.get(Q(playlist_id=playlist_id) & Q(is_in_db=True))
@@ -351,33 +313,27 @@ def order_playlist_by(request, playlist_id, order_by):
         return HttpResponse("Something went wrong :(")
 
     return HttpResponse(loader.get_template("intercooler/playlist_items.html").render({"playlist": playlist,
-                                                                               "playlist_items": playlist_items,
-                                                                               "videos_details": videos_details,
-                                                                               "display_text": display_text,
-                                                                               "order_by": order_by}))
+                                                                                       "playlist_items": playlist_items,
+                                                                                       "videos_details": videos_details,
+                                                                                       "display_text": display_text,
+                                                                                       "order_by": order_by}))
 
 
 @login_required
-def order_playlists_by(request, playlist_type, order_by):
-    print("GET", request.GET)
-    print("POST", request.POST)
-    print("CONTENT PARAMS", request.content_params)
-    print("HEAD", request.headers)
-    print("BODY", request.body)
-
+def order_playlists_by(request, library_type, order_by):
     watching = False
 
-    if playlist_type == "" or playlist_type.lower() == "all":
+    if library_type == "" or library_type.lower() == "all":
         playlists = request.user.playlists.all()
-    elif playlist_type.lower() == "favorites":
+    elif library_type.lower() == "favorites":
         playlists = request.user.playlists.filter(Q(is_favorite=True) & Q(is_in_db=True))
-    elif playlist_type.lower() in ["watching", "plan-to-watch"]:
-        playlists = request.user.playlists.filter(Q(marked_as=playlist_type.lower()) & Q(is_in_db=True))
-        if playlist_type.lower() == "watching":
+    elif library_type.lower() in ["watching", "plan-to-watch"]:
+        playlists = request.user.playlists.filter(Q(marked_as=library_type.lower()) & Q(is_in_db=True))
+        if library_type.lower() == "watching":
             watching = True
-    elif playlist_type.lower() == "imported":
+    elif library_type.lower() == "imported":
         playlists = request.user.playlists.filter(Q(is_user_owned=False) & Q(is_in_db=True))
-    elif playlist_type.lower() == "user-owned":
+    elif library_type.lower() == "user-owned":
         playlists = request.user.playlists.filter(Q(is_user_owned=True) & Q(is_in_db=True))
     else:
         return HttpResponse("Not found.")
@@ -430,7 +386,7 @@ def mark_playlist_as(request, playlist_id, mark_as):
 
 @login_required
 def playlists_home(request):
-    return render(request, 'playlists_home.html')
+    return render(request, 'library.html')
 
 
 @login_required
@@ -583,7 +539,6 @@ def mark_video_watched(request, playlist_id, video_id):
 ###########
 
 
-
 @login_required
 def manage_playlists(request):
     return render(request, "manage_playlists.html")
@@ -1168,3 +1123,13 @@ def video_completion_times(request, video_id):
         <h6>At 1.75x speed: {getHumanizedTimeString(video_duration / 1.75)}</h6>
         <h6>At 2x speed: {getHumanizedTimeString(video_duration / 2)}</h6>
     """)
+
+
+@login_required
+@require_POST
+def add_video_user_label(request, video_id):
+    video = request.user.videos.get(video_id=video_id)
+    if "user_label" in request.POST:
+        video.user_label = bleach.clean(request.POST["user_label"])
+        video.save(update_fields=['user_label'])
+    return redirect('video', video_id=video_id)

+ 2 - 2
apps/search/templates/intercooler/search_untube_results.html

@@ -2,7 +2,7 @@
 
 {% if view_mode == "playlists" %}
     <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
-        <h1 class="h2">{% if search_query == "" %}All{% endif %} Playlists {% if search_query != "" %}results for '{{ search_query|escape }}' {% endif %} <span class="badge bg-primary rounded-pill">{{ playlists.count|default:"0" }}</span></h1>
+        <h1 class="h2">{% if search_query == "" %}{{ playlist_type }}{% endif %} Playlists {% if search_query != "" %}results for '{{ search_query|escape }}' {% endif %} <span class="badge bg-primary rounded-pill">{{ playlists.count|default:"0" }}</span></h1>
     </div>
 
     <div class="row row-cols-1 row-cols-md-4 g-4">
@@ -15,7 +15,7 @@
 {% else %}
 
     <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
-        <h1 class="h2">{% if search_query == "" %}All{% endif %} Videos <span class="badge bg-primary rounded-pill">{{ videos.count }}</span> {% if videos.count > 250 %}(Only top 100 results shown){% endif %}</h1>
+        <h1 class="h2">{% if search_query == "" %}{{ videos_type }}{% endif %} Videos {% if search_query != "" %}results for '{{ search_query|escape }}' {% endif %} <span class="badge bg-primary rounded-pill">{{ videos.count }}</span> {% if videos.count > 100 %}<small>(only top 100 results shown)</small>{% endif %}</h1>
     </div>
 
     <div>

+ 163 - 92
apps/search/templates/search_untube_page.html

@@ -5,132 +5,203 @@
 {% block content %}
     <br>
     <script>
-    window.onkeydown = function( event ) {
-        if ( event.keyCode === 27 ) {
-            window.close(); // closes current tab
-        }
-    };
+        window.onkeydown = function( event ) {
+            if ( event.keyCode === 27 ) {
+                window.close(); // closes current tab
+            }
+        };
     </script>
 
-    <div class="d-flex justify-content-center">
+    <div class="d-flex justify-content-center mb-3">
         <h1> Search all of UnTube
             {% if user.profile.open_search_new_tab %}<h6>Press <kbd>Esc</kbd> to close.</h6>{% endif %}
         </h1>
     </div>
-        <div id="search-playlist-form">
+    <div id="search-playlist-form">
 
         <input class="form-control me-lg-2" type="text"
-               id="untubeSearchBar"
-                name="search" placeholder="Search UnTube (leave this empty to just filter playlists by tags or filter videos by channels)"
-                hx-post="{% url 'search_UnTube' %}"
-                hx-trigger="keyup changed delay:700ms"
-                hx-target="#untube-searchbar-results"
-                hx-include="[id='search-playlist-form']"
-                hx-indicator="#spinner" autofocus>
+            id="untubeSearchBar" value="{{ query }}"
+            name="search" placeholder="Search for a specific playlist or a video here (leave this empty to just filter playlists by tags or filter videos by channels)"
+            hx-post="{% url 'search_UnTube' %}"
+            hx-trigger="keyup changed delay:700ms"
+            hx-target="#untube-searchbar-results"
+            hx-include="[id='search-playlist-form']"
+            hx-indicator="#spinner" autofocus onfocus="this.setSelectionRange(this.value.length, this.value.length);">
 
         <br>
 
         <div class="row d-flex justify-content-center">
-            <div class="col-md-6" id="playlists">
-                Filter by playlist tags:
-                <select class="visually-hidden" onchange="triggerSubmit()"
-                     id="choices-playlist-tags" name="playlist-tags" placeholder="Add playlist tags to search within" multiple>
-                    {% for tag in user.playlist_tags.all %}
-                    <option value="{{ tag.name }}" hx-post="{% url 'search_UnTube' %}">{{ tag.name }}</option>
-                    {% endfor %}
-                </select>
+            <div class="col-lg-7" id="playlists">
+                <div class="row">
+                    <div class="col">
+                        Filter by playlist tags:
+                        <select class="visually-hidden" onchange="triggerSubmit()"
+                            id="choices-playlist-tags" name="playlist-tags" placeholder="Add playlist tags to search within" multiple>
+                            {% for tag in user.playlist_tags.all %}
+                                <option value="{{ tag.name }}" hx-post="{% url 'search_UnTube' %}" {% if pl_tag == tag.name %}selected{% endif %}>{{ tag.name }}</option>
+                            {% endfor %}
+                        </select>
+
+                    </div>
+                    <div class="col">
+                        <div class="d-flex justify-content-start">
+                            <div>
+                                Playlist type:
+                                <select onchange="triggerSubmit()" class="form-select mt-1" name="playlistsType">
+                                    <option value="All" {% if item_type == "all" %}selected{% endif %}>All</option>
+                                    <option value="Favorite" {% if item_type == "favorites" %}selected{% endif %}>Favorites</option>
+                                    <option value="Watching" {% if item_type == "watching" %}selected{% endif %}>Watching</option>
+                                    <option value="Plan to Watch" {% if item_type == "plan-to-watch" %}selected{% endif %}>Plan to Watch</option>
+                                    <option value="Owned" {% if item_type == "user-owned" %}selected{% endif %}>Owned</option>
+                                    <option value="Imported" {% if item_type == "imported" %}selected{% endif %}>Imported</option>
+                                    <option value="Mix" {% if item_type == "yt-mix" %}selected{% endif %}>YT Mix</option>
+                                </select>
+                            </div>
+                            <div class="ms-3">
+                                Sort by:
+                                <select onchange="triggerSubmit()" class="form-select mt-1" name="sortPlaylistsBy">
+                                    <option value="recently-accessed" selected>Recently accessed</option>
+                                    <option value="playlist-duration-in-seconds" >Duration</option>
+                                    <option value="video-count" >Number of videos</option>
+                                </select>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
             </div>
-            <div class="col-md-6" id="videos">
-                Filter by video channels:
-                <select class="visually-hidden" onchange="triggerSubmit()"
-                     id="choices-channels" name="channel-names" placeholder="Select channels to search within" multiple>
-                    {% for channel in user.profile.get_channels_list %}
-                    <option value="{{ channel }}" hx-post="{% url 'search_UnTube' %}">{{ channel }}</option>
-                    {% endfor %}
-                </select>
+            <div class="col-lg-8" id="videos">
+
+                <div class="row">
+                    <div class="col">
+                        Filter by video channels:
+                        <select class="visually-hidden" onchange="triggerSubmit()"
+                            id="choices-channels" name="channel-names" placeholder="Select channels to search within" multiple>
+                            {% for channel in user.profile.get_channels_list %}
+                                <option value="{{ channel }}" hx-post="{% url 'search_UnTube' %}">{{ channel }}</option>
+                            {% endfor %}
+                        </select>
+                    </div>
+                    <div class="col">
+                        <div class="d-flex justify-content-start">
+                            <div>
+
+                                Video type:
+                                <select onchange="triggerSubmit()" class="form-select mt-1" name="videosType">
+                                    <option value="All" {% if item_type == "all" %}selected{% endif %}>All</option>
+                                    <option value="Favorite" {% if item_type == "favorite" %}selected{% endif %}>Favorite</option>
+                                    <option value="Watched" {% if item_type == "watched" %}selected{% endif %}>Watched</option>
+                                </select>
+                            </div>
+                            <div class="ms-3">
+                                Sort by:
+                                <select onchange="triggerSubmit()" class="form-select mt-1" name="sortVideosBy">
+                                    <option value="recently-accessed" selected>Recently accessed</option>
+                                    <option value="video-duration-in-seconds" >Duration</option>
+                                    <option value="most-liked" >Most liked</option>
+                                    <option value="most-views" >Most views</option>
+                                    <option value="date-uploaded" >Date uploaded</option>
+                                </select>
+                            </div>
+
+                        </div>
+                    </div>
+                </div>
+                <div class="d-flex justify-content-center mt-2">
+                    <input class="form-check-input" type="checkbox" name="has-cc" id="mustHaveCCcb" onclick="triggerSubmit()">
+                    <label class="form-check-label ms-2" for="mustHaveCCcb">
+                        Must have CC
+                    </label>
+                </div>
+            </div>
+            <br>
+            <div class="d-flex justify-content-center mt-3">
+
+                <div class="form-check me-5">
+                    <input onclick="hideShow()" hx-post="{% url 'search_UnTube' %}"
+                        hx-trigger="click"
+                        hx-target="#untube-searchbar-results"
+                        hx-include="[id='search-playlist-form']"
+                        hx-indicator="#spinner"
+                        class="form-check-input" type="radio" name="search-settings" value="playlists" id="playlists-cb" {% if mode == "playlists" %}checked{% endif %}>
+                    <label class="form-check-label " for="playlists-cb">
+                        Playlists
+                    </label>
+                </div>
+                <div class="form-check" >
+                    <input onclick="hideShow();" hx-post="{% url 'search_UnTube' %}"
+                        hx-trigger="click"
+                        hx-target="#untube-searchbar-results"
+                        hx-include="[id='search-playlist-form']"
+                        hx-indicator="#spinner"
+                        class="form-check-input" type="radio" name="search-settings" value="videos" id="videos-cb" {% if mode == "videos" %}checked{% endif %}>
+                    <label class="form-check-label" for="videos-cb">
+                        Videos
+                    </label>
+                </div>
             </div>
         </div>
-        <br>
-    <div class="d-flex justify-content-center">
-
-        <div class="form-check me-5">
-            <input onclick="hideShow()" hx-post="{% url 'search_UnTube' %}"
-        hx-trigger="click"
-        hx-target="#untube-searchbar-results"
-        hx-include="[id='search-playlist-form']"
-        hx-indicator="#spinner"
-                           class="form-check-input" type="radio" name="search-settings" value="playlists" id="playlists-cb" checked>
-            <label class="form-check-label " for="playlists-cb">
-                    Playlists
-            </label>
-        </div>
-         <div class="form-check" >
-            <input onclick="hideShow();" hx-post="{% url 'search_UnTube' %}"
-        hx-trigger="click"
-        hx-target="#untube-searchbar-results"
-        hx-include="[id='search-playlist-form']"
-        hx-indicator="#spinner"
-                    class="form-check-input" type="radio" name="search-settings" value="videos" id="videos-cb">
-                  <label class="form-check-label" for="videos-cb">
-                    Videos
-                  </label>
-        </div>
-    </div>
-</div>
 
-    <div id="spinner" class="htmx-indicator d-flex justify-content-center p-3">
-        <div class="spinner-border text-light" role="status">
+        <div id="spinner" class="htmx-indicator d-flex justify-content-center p-3">
+            <div class="spinner-border text-warning" role="status">
+            </div>
         </div>
-    </div>
 
-    <div id="untube-searchbar-results">
+        <div id="untube-searchbar-results">
 
-    </div>
+        </div>
 
-    <button class="scrollToTopBtn sticky-top">
-<i class="fa fa-angle-double-up fa-lg"></i></button>
+        <button class="scrollToTopBtn sticky-top">
+            <i class="fa fa-angle-double-up fa-lg"></i></button>
 
-    <script type="application/javascript">
+        <script type="application/javascript">
 
-    $(document).ready(function(){
+            $(document).ready(function(){
 
-                        videos.style.display = 'none';
+                {% if mode == "playlists" %}
+                    document.getElementById("videos").style.display = 'none';
+                {% else %}
+                    document.getElementById("playlists").style.display = 'none';
+                {% endif %}
 
-        // multiple choices select search box
-        var choicesPlaylistTags = new Choices('#choices-playlist-tags', {
+                // multiple choices select search box
+                var choicesPlaylistTags = new Choices('#choices-playlist-tags', {
                     removeItemButton: true,
+                    noChoicesText: "Looks like you haven't created any playlist tags yet!"
                 });
 
-        var choicesChannels = new Choices('#choices-channels', {
+                var choicesChannels = new Choices('#choices-channels', {
                     removeItemButton: true,
                 });
-    });
+
+                triggerSubmit();
+            });
 
 
-        function hideShow() {
-            var playlistsCB = document.getElementById("playlists-cb");
+            function hideShow() {
+                var playlistsCB = document.getElementById("playlists-cb");
 
-            var videos = document.getElementById("videos");
-            var playlists = document.getElementById("playlists");
-            if (playlistsCB.checked) {
-                videos.style.display = 'none';
-                playlists.style.display = 'block';
-            } else {
-                videos.style.display = 'block';
-                playlists.style.display = 'none';
+                var videos = document.getElementById("videos");
+                var playlists = document.getElementById("playlists");
+                if (playlistsCB.checked) {
+                    videos.style.display = 'none';
+                    playlists.style.display = 'block';
+                } else {
+                    videos.style.display = 'block';
+                    playlists.style.display = 'none';
+                }
             }
-        }
-        function triggerSubmit() {
-            var playlistsCB = document.getElementById("playlists-cb");
-            var videosCB = document.getElementById("videos-cb");
+            function triggerSubmit() {
+                var playlistsCB = document.getElementById("playlists-cb");
+                var videosCB = document.getElementById("videos-cb");
 
-            if (playlistsCB.checked) {
-                playlistsCB.click();
-            } else {
-                videosCB.click();
+                if (playlistsCB.checked) {
+                    playlistsCB.click();
+                } else {
+                    videosCB.click();
 
+                }
             }
-        }
-    </script>
+        </script>
 
-{% endblock %}
+{% endblock %}

+ 75 - 2
apps/search/views.py

@@ -12,7 +12,33 @@ from apps.main.models import Video, Tag
 @login_required
 def search(request):
     if request.method == "GET":
-        return render(request, 'search_untube_page.html', {"playlists": request.user.playlists.all()})
+        print(request.GET)
+        if 'mode' in request.GET:
+            mode = request.GET['mode']
+        else:
+            mode = "playlists"
+
+        if 'type' in request.GET:
+            item_type = request.GET["type"]
+        else:
+            item_type = "all"
+
+        if 'query' in request.GET:
+            query = request.GET["query"]
+        else:
+            query = ''
+
+        if 'tag' in request.GET:
+            pl_tag = request.GET["tag"]
+        else:
+            pl_tag = ""
+
+        return render(request, 'search_untube_page.html',
+                      {"playlists": request.user.playlists.all(),
+                       "mode": mode,
+                       "item_type": item_type,
+                       "query": query,
+                       "pl_tag": pl_tag})
     else:
         return redirect('home')
 
@@ -26,7 +52,22 @@ def search_UnTube(request):
     print(search_query)
 
     if request.POST['search-settings'] == 'playlists':
+        playlist_type = bleach.clean(request.POST["playlistsType"])
+
         all_playlists = request.user.playlists.filter(is_in_db=True)
+        if playlist_type == "Favorite":
+            all_playlists = all_playlists.filter(is_favorite=True)
+        elif playlist_type == "Watching":
+            all_playlists = all_playlists.filter(marked_as="watching")
+        elif playlist_type == "Plan to Watch":
+            all_playlists = all_playlists.filter(marked_as="plan-to-watch")
+        elif playlist_type == "Owned":
+            all_playlists = all_playlists.filter(is_user_owned=True)
+        elif playlist_type == "Imported":
+            all_playlists = all_playlists.filter(is_user_owned=False)
+        elif playlist_type == "Mix":
+            all_playlists = all_playlists.filter(is_yt_mix=True)
+
         if 'playlist-tags' in request.POST:
             tags = request.POST.getlist('playlist-tags')
             for tag in tags:
@@ -38,12 +79,28 @@ def search_UnTube(request):
         if search_query.strip() == "":
             playlists = all_playlists
 
+        order_by = bleach.clean(request.POST['sortPlaylistsBy'])
+        if order_by == 'recently-accessed':
+            playlists = playlists.order_by("-updated_at")
+        elif order_by == 'playlist-duration-in-seconds':
+            playlists = playlists.order_by("-playlist_duration_in_seconds")
+        elif order_by == 'video-count':
+            playlists = playlists.order_by("-video_count")
+
         return HttpResponse(loader.get_template("intercooler/search_untube_results.html")
                             .render({"playlists": playlists,
                                      "view_mode": "playlists",
-                                     "search_query": search_query}))
+                                     "search_query": search_query,
+                                     "playlist_type": playlist_type}))
     else:
+        videos_type = bleach.clean(request.POST["videosType"])
+
         all_videos = request.user.videos.filter(is_unavailable_on_yt=False)
+        if videos_type == "Favorite":
+            all_videos = all_videos.filter(is_favorite=True)
+        elif videos_type == "Watched":
+            all_videos = all_videos.filter(is_marked_as_watched=True)
+
         if 'channel-names' in request.POST:
             channels = request.POST.getlist('channel-names')
             all_videos = all_videos.filter(channel_name__in=channels)
@@ -54,9 +111,25 @@ def search_UnTube(request):
         if search_query.strip() == "":
             videos = all_videos
 
+        order_by = bleach.clean(request.POST['sortVideosBy'])
+        if order_by == 'recently-accessed':
+            videos = videos.order_by("-updated_at")
+        elif order_by == 'video-duration-in-seconds':
+            videos = videos.order_by("-duration_in_seconds")
+        elif order_by == 'most-liked':
+            videos = videos.order_by("-like_count")
+        elif order_by == 'most-views':
+            videos = videos.order_by("-view_count")
+        elif order_by == 'date-uploaded':
+            videos = videos.order_by("-published_at")
+
+        if 'has-cc' in request.POST:
+            videos = videos.filter(has_cc=True)
+
         return HttpResponse(loader.get_template("intercooler/search_untube_results.html")
                             .render({"videos": videos,
                                      "view_mode": "videos",
+                                     "videos_type": videos_type,
                                      "search_query": search_query}))
 
 

+ 2 - 0
apps/users/views.py

@@ -121,6 +121,8 @@ def log_out(request):
     if "troll" in request.GET:
         print("TROLLED")
         messages.success(request, "Hee Hee")
+    else:
+        messages.success(request, "Successfully logged out. Hope to see you back again!")
 
     return redirect('/')
 

+ 7 - 11
templates/base.html

@@ -144,26 +144,22 @@
                         </li>
 
                         <li class="nav-item dropdown">
-                            <a class="nav-link dropdown-toggle" href="#" id="libraryDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+                            <a class="nav-link" href="{% url 'library' 'home' %}">
                                 Library
                             </a>
-                            <ul class="dropdown-menu" aria-labelledby="libraryDropdown" style="z-index: 1021;">
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'home' %}">Playlists</a></li>
-                                <li><a class="dropdown-item" href="{% url 'all_videos' 'home' %}">Videos</a></li>
-                            </ul>
                         </li>
                         <li class="nav-item dropdown">
                             <a class="nav-link dropdown-toggle" href="#" id="quickViewDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                                 Quick View
                             </a>
                             <ul class="dropdown-menu" aria-labelledby="quickViewDropdown" style="z-index: 1021;">
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'favorites' %}">Favorites</a></li>
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'watching' %}">Watching</a></li>
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'plan-to-watch' %}">Plan to Watch</a></li>
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'user-owned' %}">Your YT Playlists</a></li>
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'imported' %}">Imported</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'favorites' %}">Favorites</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'watching' %}">Watching</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'plan-to-watch' %}">Plan to Watch</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'user-owned' %}">Your YT Playlists</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'imported' %}">Imported</a></li>
                                 <li><hr class="dropdown-divider"></li>
-                                <li><a class="dropdown-item" href="{% url 'all_playlists' 'all' %}">View all</a></li>
+                                <li><a class="dropdown-item" href="{% url 'library' 'all' %}">View all</a></li>
                             </ul>
                         </li>