Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [5.13.5] - 2026-09-08

### Fixed

- **Timezone `local_date` crash on plain dates** — Dashboard crashed when `Task.due_date` (a calendar date) was piped through `|local_date`, which assumed a datetime and read `.tzinfo`. Skip timezone conversion for date-only values, matching `format_user_datetime`.
- **Idle auto-stop on paused timers (#752)** — Paused timers stop heartbeating, so the idle sweep treated them as idle: “Still working?” push, needs-review flag, then optional auto-stop. Guard the idle query on `paused_at IS NULL` so intentionally paused timers are skipped.
- **Manual entry single-client lock (#753)** — The manual time-entry form passed `force_selectable=True` to the client select, which bypassed the single-client readonly lock. Dropping the flag restores the pre-filled lock when the org has exactly one client.

### Changed

- **Client versions** — Synced Electron (`desktop/package.json`), Flutter (`mobile/pubspec.yaml`), and Chromium extension (`browser-extension/manifest.json` / `package.json`) to **5.13.5** with the webapp (`setup.py`).

### Documentation

- **Version** — Bumped `setup.py` to **5.13.5** (single source of truth for the application version).

## [5.13.4] - 2026-09-04

### Fixed
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ TimeTracker has been continuously enhanced with powerful new features! Here's wh

**Current version** is defined in `setup.py` (single source of truth). See [CHANGELOG.md](CHANGELOG.md) for versioned release history.

### ✨ Highlights of v5.13.5

**Patch (5.13.5):** **Timezone `local_date`** — date-only values (e.g. task due dates) no longer crash the dashboard filter. **Idle skip paused (#752)** — paused timers are excluded from idle notify / needs-review / auto-stop. **Manual entry single-client (#753)** — restores the readonly pre-filled client lock when the org has one client. See [CHANGELOG.md](CHANGELOG.md#5135---2026-09-08).

### ✨ Highlights of v5.13.4

**Patch (5.13.4):** **Alembic multiple heads** — merge migration `184_merge_183_heads` rejoins the parallel `183` device-token and idle needs-review branches so `flask db upgrade` has a single head. See [CHANGELOG.md](CHANGELOG.md#5134---2026-09-04).
Expand Down
4 changes: 4 additions & 0 deletions app/utils/timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ def format_local_datetime(utc_dt, format_str="%Y-%m-%d %H:%M"):
if utc_dt is None:
return ""

# Plain calendar dates have no time component; timezone conversion does not apply.
if isinstance(utc_dt, date) and not isinstance(utc_dt, datetime):
return utc_dt.strftime(format_str)

local_dt = utc_to_local(utc_dt)
return local_dt.strftime(format_str)

Expand Down
2 changes: 1 addition & 1 deletion browser-extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "TimeTracker Timer",
"version": "5.13.4",
"version": "5.13.5",
"description": "Start and stop TimeTracker timers from your browser toolbar.",
"permissions": [
"storage",
Expand Down
2 changes: 1 addition & 1 deletion browser-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "timetracker-browser-extension",
"private": true,
"version": "5.13.4",
"version": "5.13.5",
"description": "TimeTracker Chromium extension (Manifest V3)",
"type": "module",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions desktop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "timetracker-desktop",
"version": "5.13.4",
"version": "5.13.5",
"description": "TimeTracker desktop app for Windows, Linux, and macOS",
"main": "src/main/main.js",
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions docs/mobile-desktop-apps/DESKTOP_WEBAPP_GAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Living checklist for bringing the Electron desktop client up to speed with the F

| Component | Version | Source |
|-----------|---------|--------|
| Web / backend | 5.13.4 | `setup.py` |
| Desktop | 5.13.4 | `desktop/package.json` |
| Mobile | 5.13.4 | `mobile/pubspec.yaml` |
| Web / backend | 5.13.5 | `setup.py` |
| Desktop | 5.13.5 | `desktop/package.json` |
| Mobile | 5.13.5 | `mobile/pubspec.yaml` |

## What desktop has

Expand Down
4 changes: 2 additions & 2 deletions mobile/android/local.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
flutter.versionCode=51304
flutter.versionName=5.13.4
flutter.versionCode=51305
flutter.versionName=5.13.5
flutter.sdk=C:\\Flutter\\flutter
sdk.dir=C:\\Users\\dries\\AppData\\Local\\Android\\Sdk
flutter.buildMode=release
2 changes: 1 addition & 1 deletion mobile/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: timetracker_mobile
description: TimeTracker mobile app for Android and iOS
publish_to: 'none'
version: 5.13.4+1
version: 5.13.5+1

environment:
sdk: '>=3.0.0 <4.0.0'
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name='timetracker',
version='5.13.4',
version='5.13.5',
packages=find_packages(),
include_package_data=True,
package_data={
Expand Down
15 changes: 15 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ def test_local_date_filter(app):
assert isinstance(result, str)


@pytest.mark.unit
@pytest.mark.utils
def test_local_date_filter_plain_date(app):
"""Test local_date filter accepts plain date objects (e.g. Task.due_date)."""
register_template_filters(app)
with app.app_context():
filter_func = app.jinja_env.filters.get("local_date")
plain_date = datetime.date(2024, 1, 15)
result = filter_func(plain_date)
assert result is not None
assert isinstance(result, str)
assert "2024" in result
assert "15" in result or "01" in result


@pytest.mark.unit
@pytest.mark.utils
def test_local_date_filter_none(app):
Expand Down
Loading