[templates] Add pill buttons to calendar
This commit is contained in:
@ -93,7 +93,7 @@ fetching and simple saving.
|
|||||||
:LOGBOOK:
|
:LOGBOOK:
|
||||||
CLOCK: [2025-07-09 Wed 09:55]--[2025-07-09 Wed 10:15] => 0:20
|
CLOCK: [2025-07-09 Wed 09:55]--[2025-07-09 Wed 10:15] => 0:20
|
||||||
:END:
|
:END:
|
||||||
* Backlog [26/42]
|
* Backlog [26/42] :vrobbler:project:personal:
|
||||||
** TODO [#C] Add sentiment parsing for Scrobbles with notes :vrobbler:project:scrobbles:sentiment:
|
** TODO [#C] Add sentiment parsing for Scrobbles with notes :vrobbler:project:scrobbles:sentiment:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:ID: 37781d6a-f3b0-48b2-bf98-33c2c791cf85
|
:ID: 37781d6a-f3b0-48b2-bf98-33c2c791cf85
|
||||||
@ -496,6 +496,7 @@ or at least make it optional, and then require a M2M between Track and Artist.
|
|||||||
Then this one would be a Track by both `Matt Sweeney` and `Bonnie "Prince"
|
Then this one would be a Track by both `Matt Sweeney` and `Bonnie "Prince"
|
||||||
Billy`
|
Billy`
|
||||||
|
|
||||||
|
** TODO [#A] Allow special parameter to re-import already processed GPX files :imports:gpx:
|
||||||
** DONE [#A] Add CSS Grid calendar view for scrobbles :vrobbler:personal:project:templates:feature:
|
** DONE [#A] Add CSS Grid calendar view for scrobbles :vrobbler:personal:project:templates:feature:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:ID: be915acf-d803-466a-8770-823819ebf2a9
|
:ID: be915acf-d803-466a-8770-823819ebf2a9
|
||||||
|
|||||||
@ -1305,6 +1305,8 @@ class ScrobbleCalendarView(LoginRequiredMixin, TemplateView):
|
|||||||
"Mood": "🥰",
|
"Mood": "🥰",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFAULT_EXCLUDE = ["Task"]
|
||||||
|
|
||||||
MONTH_COLORS = [
|
MONTH_COLORS = [
|
||||||
"#db7a7a", # Jan
|
"#db7a7a", # Jan
|
||||||
"#db847a", # Feb
|
"#db847a", # Feb
|
||||||
@ -1345,12 +1347,18 @@ class ScrobbleCalendarView(LoginRequiredMixin, TemplateView):
|
|||||||
prev_month = month_start - timedelta(days=1)
|
prev_month = month_start - timedelta(days=1)
|
||||||
next_month = month_end + timedelta(days=1)
|
next_month = month_end + timedelta(days=1)
|
||||||
|
|
||||||
|
media_type_filter = self.request.GET.get("media_type")
|
||||||
|
if media_type_filter and media_type_filter in self.CALENDAR_MEDIA_TYPES:
|
||||||
|
active_types = [media_type_filter]
|
||||||
|
else:
|
||||||
|
active_types = [t for t in self.CALENDAR_MEDIA_TYPES if t not in self.DEFAULT_EXCLUDE]
|
||||||
|
|
||||||
scrobbles = (
|
scrobbles = (
|
||||||
Scrobble.objects.filter(
|
Scrobble.objects.filter(
|
||||||
user=self.request.user,
|
user=self.request.user,
|
||||||
timestamp__date__gte=month_start,
|
timestamp__date__gte=month_start,
|
||||||
timestamp__date__lte=month_end,
|
timestamp__date__lte=month_end,
|
||||||
media_type__in=self.CALENDAR_MEDIA_TYPES,
|
media_type__in=active_types,
|
||||||
)
|
)
|
||||||
.select_related("task", "birding_location", "food", "trail", "video_game", "book", "mood")
|
.select_related("task", "birding_location", "food", "trail", "video_game", "book", "mood")
|
||||||
.order_by("timestamp")
|
.order_by("timestamp")
|
||||||
@ -1400,6 +1408,8 @@ class ScrobbleCalendarView(LoginRequiredMixin, TemplateView):
|
|||||||
"current_month": today.isoformat()[:7],
|
"current_month": today.isoformat()[:7],
|
||||||
"day_names": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
"day_names": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||||
"month_color": month_color,
|
"month_color": month_color,
|
||||||
|
"active_filter": media_type_filter or "",
|
||||||
|
"media_types": [{"name": mt, "emoji": self.MEDIA_EMOJI.get(mt, "📌")} for mt in self.CALENDAR_MEDIA_TYPES],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return ctx
|
return ctx
|
||||||
|
|||||||
@ -13,25 +13,48 @@ header.navbar { display: none !important; }
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
.top-bar { display: none; }
|
||||||
.home-btn {
|
.home-btn {
|
||||||
position: fixed;
|
margin-left: auto;
|
||||||
top: 12px;
|
padding: 4px 16px;
|
||||||
left: 12px;
|
|
||||||
z-index: 100;
|
|
||||||
background: rgba(255,255,255,0.85);
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 6px 16px;
|
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #555;
|
color: #555;
|
||||||
|
background: rgba(255,255,255,0.85);
|
||||||
|
border: 1px solid #ddd;
|
||||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||||
width: auto;
|
|
||||||
}
|
}
|
||||||
.home-btn:hover {
|
.home-btn:hover {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
.filter-bar {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.filter-bar a {
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 16px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #666;
|
||||||
|
background: rgba(255,255,255,0.5);
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
transition: all 0.15s;
|
||||||
|
}
|
||||||
|
.filter-bar a:hover {
|
||||||
|
background: rgba(255,255,255,0.8);
|
||||||
|
border-color: #aaa;
|
||||||
|
}
|
||||||
|
.filter-bar a.active {
|
||||||
|
background: {{ month_color }};
|
||||||
|
color: #fff;
|
||||||
|
border-color: {{ month_color }};
|
||||||
|
}
|
||||||
.calendar-wrapper {
|
.calendar-wrapper {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -141,8 +164,16 @@ header.navbar { display: none !important; }
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a href="/" class="home-btn">Home</a>
|
|
||||||
<div class="calendar-wrapper">
|
<div class="calendar-wrapper">
|
||||||
|
<div class="filter-bar">
|
||||||
|
<a href="?date={{ current_month }}"
|
||||||
|
{% if not active_filter %}class="active"{% endif %}>All</a>
|
||||||
|
{% for mt in media_types %}
|
||||||
|
<a href="?date={{ current_month }}&media_type={{ mt.name }}"
|
||||||
|
{% if active_filter == mt.name %}class="active"{% endif %}>{{ mt.emoji }} {{ mt.name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="/" class="home-btn">Home</a>
|
||||||
|
</div>
|
||||||
<div class="calendar-grid">
|
<div class="calendar-grid">
|
||||||
<div class="month-banner">
|
<div class="month-banner">
|
||||||
<a href="?date={{ prev_month }}">←</a>
|
<a href="?date={{ prev_month }}">←</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user