Compare commits
	
		
			1 Commits
		
	
	
		
			0.2.5
			...
			beec919b2e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| beec919b2e | 
@ -1,8 +1,5 @@
 | 
				
			|||||||
.git
 | 
					src/web/static/*
 | 
				
			||||||
.githooks
 | 
					 | 
				
			||||||
.mypy_cache
 | 
					 | 
				
			||||||
.pytest_cache
 | 
					 | 
				
			||||||
.venv
 | 
					.venv
 | 
				
			||||||
 | 
					.githooks
 | 
				
			||||||
.vscode
 | 
					.vscode
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
src/web/static/*
 | 
					 | 
				
			||||||
@ -1,11 +1,8 @@
 | 
				
			|||||||
## 0.2.5 / 2023-01-18 17:01+01:00
 | 
					## Unreleased
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* New
 | 
					* New
 | 
				
			||||||
  * When adding session, pre-select game with the last session
 | 
					  * When adding session, pre-select game with the last session
 | 
				
			||||||
* Fixed
 | 
					  * Date and time input fields now have proper pickers
 | 
				
			||||||
  * 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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.5
 | 
					ENV VERSION_NUMBER 0.2.4
 | 
				
			||||||
ENV PROD 1
 | 
					ENV PROD 1
 | 
				
			||||||
ENV PYTHONUNBUFFERED=1
 | 
					ENV PYTHONUNBUFFERED=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
[tool.poetry]
 | 
					[tool.poetry]
 | 
				
			||||||
name = "timetracker"
 | 
					name = "timetracker"
 | 
				
			||||||
version = "0.2.5"
 | 
					version = "0.2.4"
 | 
				
			||||||
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"
 | 
				
			||||||
 | 
				
			|||||||
@ -13,12 +13,26 @@ class SessionForm(forms.ModelForm):
 | 
				
			|||||||
            "duration_manual",
 | 
					            "duration_manual",
 | 
				
			||||||
            "note",
 | 
					            "note",
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					        custom_datetime_widget = forms.SplitDateTimeWidget(
 | 
				
			||||||
 | 
					            date_attrs={"type": "date"}, time_attrs={"type": "time"}
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        widgets = {
 | 
				
			||||||
 | 
					            "timestamp_start": custom_datetime_widget,
 | 
				
			||||||
 | 
					            "timestamp_end": custom_datetime_widget,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseForm(forms.ModelForm):
 | 
					class PurchaseForm(forms.ModelForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Purchase
 | 
					        model = Purchase
 | 
				
			||||||
        fields = ["game", "platform", "date_purchased", "date_refunded"]
 | 
					        fields = ["game", "platform", "date_purchased", "date_refunded"]
 | 
				
			||||||
 | 
					        custom_date_widget = forms.DateInput(
 | 
				
			||||||
 | 
					            format=("%d-%m-%Y"), attrs={"type": "date"}
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        widgets = {
 | 
				
			||||||
 | 
					            "date_purchased": custom_date_widget,
 | 
				
			||||||
 | 
					            "date_refunded": custom_date_widget,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GameForm(forms.ModelForm):
 | 
					class GameForm(forms.ModelForm):
 | 
				
			||||||
@ -31,3 +45,7 @@ class PlatformForm(forms.ModelForm):
 | 
				
			|||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Platform
 | 
					        model = Platform
 | 
				
			||||||
        fields = ["name", "group"]
 | 
					        fields = ["name", "group"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UnifiedGameForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    GameFormSet = forms.inlineformset_factory(Game, Purchase)
 | 
				
			||||||
 | 
				
			|||||||
@ -79,6 +79,10 @@ 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
 | 
				
			||||||
 | 
				
			|||||||
@ -683,34 +683,66 @@ 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 {
 | 
				
			||||||
@ -721,6 +753,26 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -729,15 +781,16 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -750,18 +803,30 @@ select {
 | 
				
			|||||||
  margin-bottom: 0.75rem;
 | 
					  margin-bottom: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mt-10 {
 | 
					 | 
				
			||||||
  margin-top: 2.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.ml-1 {
 | 
					.ml-1 {
 | 
				
			||||||
  margin-left: 0.25rem;
 | 
					  margin-left: 0.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-5 {
 | 
				
			||||||
 | 
					  margin-top: 1.25rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mb-2 {
 | 
				
			||||||
 | 
					  margin-bottom: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-10 {
 | 
				
			||||||
 | 
					  margin-top: 2.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.block {
 | 
					.block {
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.inline-block {
 | 
				
			||||||
 | 
					  display: inline-block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.inline {
 | 
					.inline {
 | 
				
			||||||
  display: inline;
 | 
					  display: inline;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -770,6 +835,30 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -810,6 +899,10 @@ select {
 | 
				
			|||||||
  max-width: 1024px;
 | 
					  max-width: 1024px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.resize {
 | 
				
			||||||
 | 
					  resize: both;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.flex-col {
 | 
					.flex-col {
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -846,6 +939,12 @@ select {
 | 
				
			|||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.truncate {
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  text-overflow: ellipsis;
 | 
				
			||||||
 | 
					  white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.text-ellipsis {
 | 
					.text-ellipsis {
 | 
				
			||||||
  text-overflow: ellipsis;
 | 
					  text-overflow: ellipsis;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -866,6 +965,10 @@ 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));
 | 
				
			||||||
@ -959,6 +1062,14 @@ 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));
 | 
				
			||||||
@ -974,6 +1085,11 @@ 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);
 | 
				
			||||||
@ -986,6 +1102,29 @@ 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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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="clear-both" href="{% url 'start_session' dataset.last.purchase.id %}">
 | 
					            <a class="block" 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" />
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,6 @@ 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:
 | 
				
			||||||
@ -76,8 +75,7 @@ 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
 | 
				
			||||||
    # cannot use dataset[0] here because that might be only partial QuerySet
 | 
					    context["last"] = Session.objects.all().last()
 | 
				
			||||||
    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"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user