Compare commits

..

4 Commits

Author SHA1 Message Date
Lukáš Kucharczyk 55c2693f32
Bump version to 0.2.5
continuous-integration/drone/push Build is passing Details
2023-01-18 17:01:37 +01:00
Lukáš Kucharczyk 972ff67050
Update CSS 2023-01-18 16:58:55 +01:00
Lukáš Kucharczyk 8ae99faa8e
Fix button taking up 100% width
Fixes #37
2023-01-18 16:58:25 +01:00
Lukáš Kucharczyk 8e4086ce83
Remove reduntant property last
Fixes #38
2023-01-18 16:57:32 +01:00
7 changed files with 19 additions and 156 deletions

View File

@ -1,7 +1,11 @@
## Unreleased ## 0.2.5 / 2023-01-18 17:01+01:00
* New * New
* When adding session, pre-select game with the last session * When adding session, pre-select game with the last session
* Fixed
* Start session now button would take up 100% width, leading to accidental clicks (https://git.kucharczyk.xyz/lukas/timetracker/issues/37)
* Removed
* Session model property `last` is already implemented by Django method `last()`, thus it was removed (https://git.kucharczyk.xyz/lukas/timetracker/issues/38)
## 0.2.4 / 2023-01-16 19:39+01:00 ## 0.2.4 / 2023-01-16 19:39+01:00

View File

@ -6,7 +6,7 @@ RUN npm install && \
FROM python:3.10.9-slim-bullseye FROM python:3.10.9-slim-bullseye
ENV VERSION_NUMBER 0.2.4 ENV VERSION_NUMBER 0.2.5
ENV PROD 1 ENV PROD 1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "timetracker" name = "timetracker"
version = "0.2.4" version = "0.2.5"
description = "A simple time tracker." description = "A simple time tracker."
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"] authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
license = "GPL" license = "GPL"

View File

@ -79,10 +79,6 @@ class Session(models.Model):
def duration_sum(self) -> str: def duration_sum(self) -> str:
return Session.objects.all().total_duration() return Session.objects.all().total_duration()
@property
def last(self) -> Manager[Any]:
return Session.objects.all().order_by("timestamp_start")[0]
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.timestamp_start != None and self.timestamp_end != None: if self.timestamp_start != None and self.timestamp_end != None:
self.duration_calculated = self.timestamp_end - self.timestamp_start self.duration_calculated = self.timestamp_end - self.timestamp_start

View File

@ -683,66 +683,34 @@ select {
width: 100%; width: 100%;
} }
.\!container {
width: 100% !important;
}
@media (min-width: 640px) { @media (min-width: 640px) {
.container { .container {
max-width: 640px; max-width: 640px;
} }
.\!container {
max-width: 640px !important;
}
} }
@media (min-width: 768px) { @media (min-width: 768px) {
.container { .container {
max-width: 768px; max-width: 768px;
} }
.\!container {
max-width: 768px !important;
}
} }
@media (min-width: 1024px) { @media (min-width: 1024px) {
.container { .container {
max-width: 1024px; max-width: 1024px;
} }
.\!container {
max-width: 1024px !important;
}
} }
@media (min-width: 1280px) { @media (min-width: 1280px) {
.container { .container {
max-width: 1280px; max-width: 1280px;
} }
.\!container {
max-width: 1280px !important;
}
} }
@media (min-width: 1536px) { @media (min-width: 1536px) {
.container { .container {
max-width: 1536px; max-width: 1536px;
} }
.\!container {
max-width: 1536px !important;
}
}
.visible {
visibility: visible;
}
.collapse {
visibility: collapse;
} }
.static { .static {
@ -753,26 +721,6 @@ select {
position: fixed; position: fixed;
} }
.\!fixed {
position: fixed !important;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.sticky {
position: sticky;
}
.\!sticky {
position: sticky !important;
}
.left-2 { .left-2 {
left: 0.5rem; left: 0.5rem;
} }
@ -781,16 +729,15 @@ select {
bottom: 0.5rem; bottom: 0.5rem;
} }
.clear-both {
clear: both;
}
.mx-auto { .mx-auto {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.my-5 {
margin-top: 1.25rem;
margin-bottom: 1.25rem;
}
.mb-4 { .mb-4 {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@ -803,28 +750,16 @@ select {
margin-bottom: 0.75rem; margin-bottom: 0.75rem;
} }
.ml-1 {
margin-left: 0.25rem;
}
.mt-5 {
margin-top: 1.25rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-10 { .mt-10 {
margin-top: 2.5rem; margin-top: 2.5rem;
} }
.block { .ml-1 {
display: block; margin-left: 0.25rem;
} }
.inline-block { .block {
display: inline-block; display: block;
} }
.inline { .inline {
@ -835,30 +770,6 @@ select {
display: flex; display: flex;
} }
.table {
display: table;
}
.table-caption {
display: table-caption;
}
.table-cell {
display: table-cell;
}
.contents {
display: contents;
}
.hidden {
display: none;
}
.\!hidden {
display: none !important;
}
.h-6 { .h-6 {
height: 1.5rem; height: 1.5rem;
} }
@ -899,10 +810,6 @@ select {
max-width: 1024px; max-width: 1024px;
} }
.resize {
resize: both;
}
.flex-col { .flex-col {
flex-direction: column; flex-direction: column;
} }
@ -939,12 +846,6 @@ select {
overflow: hidden; overflow: hidden;
} }
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.text-ellipsis { .text-ellipsis {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@ -965,10 +866,6 @@ select {
border-radius: 0.75rem; border-radius: 0.75rem;
} }
.border {
border-width: 1px;
}
.border-gray-200 { .border-gray-200 {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity)); border-color: rgb(229 231 235 / var(--tw-border-opacity));
@ -1062,14 +959,6 @@ select {
font-weight: 600; font-weight: 600;
} }
.uppercase {
text-transform: uppercase;
}
.lowercase {
text-transform: lowercase;
}
.text-white { .text-white {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
@ -1085,11 +974,6 @@ select {
color: rgb(248 113 113 / var(--tw-text-opacity)); color: rgb(248 113 113 / var(--tw-text-opacity));
} }
.text-red-700 {
--tw-text-opacity: 1;
color: rgb(185 28 28 / var(--tw-text-opacity));
}
.shadow-md { .shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
@ -1102,29 +986,6 @@ select {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
} }
.blur {
--tw-blur: blur(8px);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.invert {
--tw-invert: invert(100%);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.\!invert {
--tw-invert: invert(100%) !important;
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;
}
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.\!filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;
}
.transition { .transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;

View File

@ -18,7 +18,7 @@
{% if purchase %}<a class="dark:text-white hover:underline block" href="{% url 'list_sessions_by_game' purchase.game.id %}">See all platforms</a>{% endif %} {% if purchase %}<a class="dark:text-white hover:underline block" href="{% url 'list_sessions_by_game' purchase.game.id %}">See all platforms</a>{% endif %}
{% endif %} {% endif %}
{% if dataset.count >= 1 %} {% if dataset.count >= 1 %}
<a class="block" href="{% url 'start_session' dataset.last.purchase.id %}"> <a class="clear-both" href="{% url 'start_session' dataset.last.purchase.id %}">
<button type="button" title="Track last tracked" class="mt-10 py-1 px-2 bg-green-600 hover:bg-green-700 focus:ring-green-500 focus:ring-offset-blue-200 text-white transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg "> <button type="button" title="Track last tracked" class="mt-10 py-1 px-2 bg-green-600 hover:bg-green-700 focus:ring-green-500 focus:ring-offset-blue-200 text-white transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg ">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="self-center w-6 h-6 inline"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="self-center w-6 h-6 inline">
<path stroke-linecap="round" stroke-linejoin="round" d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.348a1.125 1.125 0 010 1.971l-11.54 6.347a1.125 1.125 0 01-1.667-.985V5.653z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.348a1.125 1.125 0 010 1.971l-11.54 6.347a1.125 1.125 0 01-1.667-.985V5.653z" />

View File

@ -66,6 +66,7 @@ def list_sessions(request, filter="", purchase_id="", platform_id="", game_id=""
dataset = Session.objects.filter(purchase__game=game_id) dataset = Session.objects.filter(purchase__game=game_id)
context["game"] = Game.objects.get(id=game_id) context["game"] = Game.objects.get(id=game_id)
else: else:
# by default, sort from newest to oldest
dataset = Session.objects.all().order_by("-timestamp_start") dataset = Session.objects.all().order_by("-timestamp_start")
for session in dataset: for session in dataset:
@ -75,7 +76,8 @@ def list_sessions(request, filter="", purchase_id="", platform_id="", game_id=""
context["total_duration"] = dataset.total_duration() context["total_duration"] = dataset.total_duration()
context["dataset"] = dataset context["dataset"] = dataset
context["last"] = Session.objects.all().last() # cannot use dataset[0] here because that might be only partial QuerySet
context["last"] = Session.objects.all().order_by("timestamp_start").last()
# charts are always oldest->newest # charts are always oldest->newest
context["chart"] = playtime_over_time_chart(dataset.order_by("timestamp_start")) context["chart"] = playtime_over_time_chart(dataset.order_by("timestamp_start"))