Browse Source

[templates] Allow going back and forward in time

Colin Powell 1 month ago
parent
commit
69aa80e6c1

+ 18 - 21
vrobbler/apps/scrobbles/models.py

@@ -604,46 +604,40 @@ class Scrobble(TimeStampedModel):
 
     @classmethod
     def for_year(cls, user, year):
-        return cls.objects.filter(timestamp__year=year, user=user)
+        return cls.objects.filter(timestamp__year=year, user=user).order_by(
+            "-timestamp"
+        )
 
     @classmethod
     def for_month(cls, user, year, month):
         return cls.objects.filter(
             timestamp__year=year, timestamp__month=month, user=user
-        )
+        ).order_by("-timestamp")
 
     @classmethod
-    def for_day(cls, user, year, day, month):
+    def for_day(cls, user, year, month, day):
         return cls.objects.filter(
             timestamp__year=year,
             timestamp__month=month,
             timestamp__day=day,
             user=user,
-        )
+        ).order_by("-timestamp")
 
     @classmethod
-    def for_day_dict(
-        cls, user_id: int, year: int, month: int, day: int
-    ) -> dict:
-        scrobbles_by_type = defaultdict(list)
-        scrobbles = cls.objects.filter(
-            timestamp__year=year,
-            timestamp__month=month,
-            timestamp__day=day,
-            user_id=user_id,
+    def for_week(cls, user, year, week):
+        return cls.objects.filter(
+            timestamp__year=year, timestamp__week=week, user=user
         ).order_by("-timestamp")
 
-        for scrobble in scrobbles:
+    @classmethod
+    def as_dict_by_type(cls, scrobble_qs: models.QuerySet) -> dict:
+        scrobbles_by_type = defaultdict(list)
+
+        for scrobble in scrobble_qs:
             scrobbles_by_type[scrobble.media_type].append(scrobble)
 
         return scrobbles_by_type
 
-    @classmethod
-    def for_week(cls, user, year, week):
-        return cls.objects.filter(
-            timestamp__year=year, timestamp__week=week, user=user
-        )
-
     @classmethod
     def in_progress_for_user(cls, user_id: int) -> models.QuerySet:
         return cls.objects.filter(
@@ -847,7 +841,10 @@ class Scrobble(TimeStampedModel):
     @property
     def elapsed_time(self) -> int | None:
         if self.played_to_completion:
-            return self.playback_position_seconds
+            if self.playback_position_seconds:
+                return self.playback_position_seconds
+            if self.media_obj.run_time_seconds:
+                return self.media_obj.run_time_seconds
         return (timezone.now() - self.timestamp).seconds
 
     @property

+ 87 - 16
vrobbler/apps/scrobbles/views.py

@@ -2,9 +2,9 @@ import calendar
 import json
 import logging
 from datetime import datetime, timedelta
+from dateutil.relativedelta import relativedelta
 
 import pendulum
-from pendulum.parsing.exceptions import ParserError
 import pytz
 from django.apps import apps
 from django.contrib import messages
@@ -109,20 +109,92 @@ class RecentScrobbleList(ListView):
         user = self.request.user
         data["date"] = ""
         if user.is_authenticated:
-            date = self.request.GET.get("date", "")
-            today = timezone.localtime(timezone.now())
+            self.queryset = self.get_queryset().filter(user=user)
             user_id = self.request.user.id
-            year = today.year
-            month = today.month
-            day = today.day
-            if date:
+
+            today = timezone.localtime(timezone.now())
+            date_str = self.request.GET.get("date", "")
+            date = today
+            if date_str:
                 try:
-                    data["date"] = pendulum.parse(date)
-                    year, month, day = date.split("-")
+                    date = pendulum.parse(date_str)
                 except:
                     pass
-
-            data = data | Scrobble.for_day_dict(user_id, year, month, day)
+            if date_str:
+                if date_str == "this_week" or "-W" in date_str:
+                    next_date = date + timedelta(weeks=+2)
+                    prev_date = date + timedelta(weeks=-1)
+                    if date.isocalendar()[1] < today.isocalendar()[1]:
+                        data[
+                            "next_link"
+                        ] = f"?date={next_date.strftime('%Y-W%W')}"
+                    data["prev_link"] = f"?date={prev_date.strftime('%Y-W%W')}"
+                    data[
+                        "title"
+                    ] = f"Week {date.strftime('%-W')} of {date.year}"
+                    data = data | Scrobble.as_dict_by_type(
+                        Scrobble.for_week(
+                            user_id, date.year, date.isocalendar()[1]
+                        )
+                    )
+                elif date_str == "this_month" or date_str.count("-") == 1:
+                    next_date = date + relativedelta(months=1)
+                    prev_date = date + relativedelta(months=-1)
+                    if date.month < today.month:
+                        data[
+                            "next_link"
+                        ] = f"?date={next_date.strftime('%Y-%m')}"
+                    data["title"] = f"{date.strftime('%B %Y')}"
+                    data["prev_link"] = f"?date={prev_date.strftime('%Y-%m')}"
+                    data = data | Scrobble.as_dict_by_type(
+                        Scrobble.for_month(user_id, date.year, date.month)
+                    )
+                elif date_str == "today" or date_str.count("-") == 2:
+                    next_date = date + timedelta(days=1)
+                    prev_date = date - timedelta(days=1)
+                    data[
+                        "prev_link"
+                    ] = f"?date={prev_date.strftime('%Y-%m-%d')}"
+                    if date < today:
+                        data[
+                            "next_link"
+                        ] = f"?date={next_date.strftime('%Y-%m-%d')}"
+                    if date == today:
+                        data["title"] = "Today"
+                    else:
+                        data["title"] = f"{date.strftime('%Y-%m-%d')}"
+                        data[
+                            "today_link"
+                        ] = f"?date={today.strftime('%Y-%m-%d')}"
+                    data = data | Scrobble.as_dict_by_type(
+                        Scrobble.for_day(
+                            user_id, date.year, date.month, date.day
+                        )
+                    )
+                elif date_str == "this_year" or date_str.count("-") == 0:
+                    next_date = date + relativedelta(years=+1)
+                    prev_date = date + relativedelta(years=-1)
+                    data["next_link"] = ""
+                    if date.year < today.year:
+                        data["title"] = f"{date.strftime('%Y')}"
+                        data["next_link"] = f"?date={next_date.year}"
+                    data["title"] = f"{date.year}"
+                    data["prev_link"] = f"?date={prev_date.year}"
+                    data = data | Scrobble.as_dict_by_type(
+                        Scrobble.for_year(user_id, date.year)
+                    )
+            else:
+                next_date = today - timedelta(days=1)
+                prev_date = today - timedelta(days=1)
+                data["title"] = "Today"
+                data["next_link"] = ""
+                data["prev_link"] = f"?date={prev_date.strftime('%Y-%m-%d')}"
+                data = data | Scrobble.as_dict_by_type(
+                    Scrobble.for_day(user_id, date.year, date.month, date.day)
+                )
+                data[
+                    "today_link"
+                ] = ""  # f"?date={today.strftime('%Y-%m-%d')}"
 
             data["active_imports"] = AudioScrobblerTSVImport.objects.filter(
                 processing_started__isnull=False,
@@ -139,9 +211,7 @@ class RecentScrobbleList(ListView):
         return data
 
     def get_queryset(self):
-        return Scrobble.objects.filter(
-            track__isnull=False, in_progress=False
-        ).order_by("-timestamp")[:15]
+        return Scrobble.objects.all().order_by("-timestamp")
 
 
 class ScrobbleLongPlaysView(TemplateView):
@@ -453,6 +523,7 @@ def gps_webhook(request):
 
     return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
 
+
 @csrf_exempt
 @api_view(["POST"])
 def emacs_webhook(request):
@@ -474,9 +545,9 @@ def emacs_webhook(request):
     if request.user.id:
         user_id = request.user.id
 
-    #scrobble = gpslogger_scrobble_location(data_dict, user_id)
+    # scrobble = gpslogger_scrobble_location(data_dict, user_id)
 
-    #if not scrobble:
+    # if not scrobble:
     #    return Response({}, status=status.HTTP_200_OK)
 
     return Response({"post_data": post_data}, status=status.HTTP_200_OK)

+ 49 - 272
vrobbler/templates/scrobbles/_last_scrobbles.html

@@ -1,305 +1,82 @@
 {% load humanize %}
 {% load naturalduration %}
-<div>
-    <p>Today <b>{{counts.today}}</b> | This Week <b>{{counts.week}}</b> | This Month <b>{{counts.month}}</b> | This Year <b>{{counts.year}}</b> | All Time <b>{{counts.alltime}}</b></p>
+<div class="row">
+    <div>
+        <p>Today <b>{{counts.today}}</b> | This Week <b>{{counts.week}}</b> | This Month <b>{{counts.month}}</b> | This Year <b>{{counts.year}}</b> | All Time <b>{{counts.alltime}}</b></p>
+    </div>
 </div>
 <div class="row">
-
+    <div class="col-md">
         {% if Track %}
-        <div class="ab-pane fade show active" id="latest-listened" role="tabpanel"
-            aria-labelledby="latest-listened-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Time</th>
-                            <th scope="col">Album</th>
-                            <th scope="col">Track</th>
-                            <th scope="col">Artist</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {{Track|length}}
-                        {% for scrobble in Track %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            {% if scrobble.track.album.cover_image %}
-                            <td><a href="{{scrobble.track.album.get_absolute_url}}"><img src="{{scrobble.track.album.cover_image_small.url}}" width=25 height=25 style="border:1px solid black;" /></aa></td>
-                            {% else %}
-                            <td><a href="{{scrobble.track.album.get_absolute_url}}">{{scrobble.track.album.name}}</a></td>
-                            {% endif %}
-                            <td><a href="{{scrobble.track.get_absolute_url }}">{{scrobble.track.title}}</a></td>
-                            <td><a href="{{scrobble.track.artist.get_absolute_url }}">{{scrobble.track.artist.name}}</aa></td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        <h2>Music</h2>
+        {% with scrobbles=Track %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
+        {% endif %}
+    </div>
+    <div class="col-md">
+
+        {% if Task %}
+        <h2>Latest tasks</h2>
+        {% with scrobbles=Task %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if Video %}
-        <div class="tab-pane fade show" id="latest-watched" role="tabpanel"
-            aria-labelledby="latest-watched-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Time</th>
-                            <th scope="col">Cover</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Series</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in Video %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            {% if scrobble.video.cover_image %}
-                            <td><img src="{{scrobble.media_obj.cover_image_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
-                            {% else %}
-                            <td></td>
-                            {% endif %}
-                            <td><a href="{{scrobble.video.get_absolute_url }}">{% if scrobble.video.tv_series%}S{{scrobble.video.season_number}}E{{scrobble.video.episode_number}} -{%endif %} {{scrobble.video.title}}</a></td>
-                            <td><a href="{{scrobble.video.tv_series.get_absolute_url }}">{% if scrobble.video.tv_series %}{{scrobble.video.tv_series}}</a>{% endif %}
-                            </td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        <h2>Videos</h2>
+        {% with scrobbles=Video %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
+        {% endif %}
+
+        {% if WebPage %}
+        <h4>Web pages</h4>
+        {% with scrobbles=WebPage %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if SportEvent %}
-        <div class="tab-pane fade show" id="latest-sports" role="tabpanel" aria-labelledby="latest-sports-tab">
-            <h2>Latest Sports</h2>
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Round</th>
-                            <th scope="col">League</th>
-                            <th scope="col">Time watched</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in SportEvent %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td>{{scrobble.sport_event.title}}</td>
-                            <td>{{scrobble.sport_event.round.name}}</td>
-                            <td>{{scrobble.sport_event.round.season.league}}</td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        <h2>Sports</h2>
+        {% with scrobbles=SportEvent %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if PodcastEpisode %}
-        <div class="tab-pane fade show" id="latest-podcasted" role="tabpanel"
-            aria-labelledby="latest-podcasted-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Podcast</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in PodcastEpisode %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td>{{scrobble.timestamp|naturaltime}}</td>
-                            <td>{{scrobble.podcast_episode.title}}</td>
-                            <td>{{scrobble.podcast_episode.podcast}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        <h2>Latest podcasts</h2>
+        {% with scrobbles=PodcastEpisode %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if VideoGame %}
         <h4>Video games</h4>
-        <div class="tab-pane fade show" id="latest-videogames" role="tabpanel"
-            aria-labelledby="latest-videogames-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Cover</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time played</th>
-                            <th scope="col">Percent complete</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in VideoGame %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            {% if scrobble.media_obj.hltb_cover %}
-                            <td><img src="{{scrobble.media_obj.hltb_cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
-                            {% endif %}
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                            <td>{{scrobble.percent_played}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        {% with scrobbles=VideoGame %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
-
         {% if BoardGame %}
         <h4>Board games</h4>
-        <div class="tab-pane fade show" id="latest-boardgames" role="tabpanel"
-            aria-labelledby="latest-boardgames-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Cover</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time played</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in BoardGame %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td><img src="{{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-        {% endif %}
-
-        {% if WebPage %}
-        <h4>Web pages</h4>
-        <div class="tab-pane fade show" id="latest-webpages" role="tabpanel"
-            aria-labelledby="latest-webpages-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time browsing</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in WebPage %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        {% with scrobbles=BoardGame %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if Beer %}
         <h4>Beers</h4>
-        <div class="tab-pane fade show" id="latest-beers" role="tabpanel"
-            aria-labelledby="latest-beers-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Cover</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time drinking</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in Beer %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td><img src="{{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        {% with scrobbles=Beer %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
         {% if Book %}
         <h4>Books</h4>
-        <div class="tab-pane fade show" id="latest-books" role="tabpanel"
-            aria-labelledby="latest-books-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Cover</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time reading</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in Book %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td><img src="{scrobble.media_obj.cover_medium.url}}" width=25 height=25 style="border:1px solid black;" /></td>
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-        {% endif %}
-
-        {% if Task %}
-        <div class="tab-pane fade show" id="latest-tasks" role="tabpanel"
-            aria-labelledby="latest-tasks-tab">
-            <div class="table-responsive">
-                <table class="table table-striped table-sm">
-                    <thead>
-                        <tr>
-                            <th scope="col">Date</th>
-                            <th scope="col">Title</th>
-                            <th scope="col">Time doing</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {% for scrobble in Task %}
-                        <tr>
-                            <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
-                            <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj.title}}</a></td>
-                            <td>{{scrobble.elapsed_time|natural_duration}}</td>
-                        </tr>
-                        {% endfor %}
-                    </tbody>
-                </table>
-            </div>
-        </div>
+        {% with scrobbles=Book %}
+        {% include "scrobbles/_scrobble_table.html" %}
+        {% endwith %}
         {% endif %}
 
     </div>

+ 7 - 0
vrobbler/templates/scrobbles/_row.html

@@ -0,0 +1,7 @@
+{% load humanize %}
+{% load naturalduration %}
+<tr>
+    <td>{% if scrobble.in_progress %}{{scrobble.media_obj.strings.verb}} now | <a class="right" href="{% url "scrobbles:finish" scrobble.uuid %}">Finish</a>{% else %}{{scrobble.timestamp|naturaltime}}{% endif %}</td>
+    <td><a href="{{scrobble.media_obj.get_absolute_url}}">{{scrobble.media_obj|truncatechars_html:50}}</a></td>
+    <td>{{scrobble.elapsed_time|natural_duration}}</td>
+</tr>

+ 22 - 0
vrobbler/templates/scrobbles/_scrobble_table.html

@@ -0,0 +1,22 @@
+{% load humanize %}
+{% load naturalduration %}
+
+<div class="tab-pane fade show" id="latest-beers" role="tabpanel"
+    aria-labelledby="latest-beers-tab">
+    <div class="table-responsive">
+        <table class="table table-striped table-sm">
+            <thead>
+                <tr>
+                    <th scope="col">Date</th>
+                    <th scope="col">Title</th>
+                    <th scope="col">Time</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for scrobble in scrobbles %}
+                {% include "scrobbles/_row.html" %}
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>

+ 25 - 4
vrobbler/templates/scrobbles/scrobble_list.html

@@ -49,9 +49,28 @@
 <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
     <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 date %}{{date|naturaltime}}{% else %}Today{% endif %}</h1>
+        <h1 class="h2">{% if date %}{{date|naturaltime}}{% else %}{{title}}{% endif %}</h1>
         <div class="btn-toolbar mb-2 mb-md-0">
             {% if user.is_authenticated %}
+            <div class="btn-group me-2">
+                {% if user.profile.lastfm_username and not user.profile.lastfm_auto_import %}
+                <form action="{% url 'scrobbles:lastfm-import' %}" method="get">
+                    <button type="submit" class="btn btn-sm btn-outline-secondary">Last.fm Sync</button>
+                </form>
+                {% endif %}
+                {% if prev_link %}
+                <a type="button" class="btn btn-sm btn-outline-secondary" href="{{prev_link}}"
+                    data-bs-target="#">Previous</a>
+                {% endif %}
+                {% if today_link %}
+                <a type="button" class="btn btn-sm btn-outline-secondary" href="{{today_link}}"
+                    data-bs-target="#">Today</a>
+                {% endif %}
+                {% if next_link %}
+                <a type="button" class="btn btn-sm btn-outline-secondary" href="{{next_link}}"
+                    data-bs-target="#">Next</a>
+                {% endif %}
+            </div>
             <div class="btn-group me-2">
                 {% if user.profile.lastfm_username and not user.profile.lastfm_auto_import %}
 
@@ -69,11 +88,13 @@
                 <button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle" id="graphDateButton"
                     data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                     <div data-feather="calendar"></div>
-                    This week
+                    {{title}}
                 </button>
                 <div class="dropdown-menu" data-bs-toggle="#graphDataChange" aria-labelledby="graphDateButton">
-                    <a class="dropdown-item" href="#">This month</a>
-                    <a class="dropdown-item" href="#">This year</a>
+                    <a class="dropdown-item" href="?date=today">Today</a>
+                    <a class="dropdown-item" href="?date=this_week">This week</a>
+                    <a class="dropdown-item" href="?date=this_month">This month</a>
+                    <a class="dropdown-item" href="?date=this_year">This year</a>
                 </div>
             </div>
         </div>