3 Commits

Author SHA1 Message Date
4a6aee8a15 add event update panel
All checks were successful
Release / meta (push) Successful in 8s
Release / linux-build (push) Successful in 6m41s
Release / android-build (push) Successful in 15m19s
Release / release-master (push) Successful in 22s
Release / release-dev (push) Successful in 24s
2025-12-16 16:14:14 +00:00
411e82807b attempt to add loco search indicator
All checks were successful
Release / meta (push) Successful in 12s
Release / linux-build (push) Successful in 6m46s
Release / android-build (push) Successful in 15m22s
Release / release-master (push) Successful in 21s
Release / release-dev (push) Successful in 23s
2025-12-16 12:47:52 +00:00
2b4d2623fc add loco timeline view 2025-12-16 12:24:53 +00:00
6 changed files with 1038 additions and 284 deletions

View File

@@ -19,6 +19,7 @@ jobs:
- mileograph
outputs:
base_version: ${{ steps.meta.outputs.base }}
release_tag: ${{ steps.meta.outputs.release_tag }}
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -29,6 +30,7 @@ jobs:
RAW_VERSION=$(awk '/^version:/{print $2}' pubspec.yaml)
BASE_VERSION=${RAW_VERSION%%+*}
echo "base=${BASE_VERSION}" >> "$GITHUB_OUTPUT"
echo "release_tag=v${BASE_VERSION}" >> "$GITHUB_OUTPUT"
android-build:
runs-on:
@@ -308,7 +310,7 @@ jobs:
id: bundle
run: |
BASE="${{ needs.meta.outputs.base_version }}"
TAG="v${BASE}"
TAG="${{ needs.meta.outputs.release_tag }}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "apk=artifacts/mileograph-${BASE}.apk" >> "$GITHUB_OUTPUT"

File diff suppressed because it is too large Load Diff

View File

@@ -423,57 +423,68 @@ class _TractionPageState extends State<TractionPage> {
),
),
const SizedBox(height: 12),
if (data.isTractionLoading && traction.isEmpty)
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 24.0),
child: CircularProgressIndicator(),
),
)
else if (traction.isEmpty)
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'No traction found',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 8),
const Text('Try relaxing the filters or sync again.'),
],
),
),
)
else
Column(
children: [
...traction.map((loco) => _buildTractionCard(context, loco)),
if (data.tractionHasMore || data.isTractionLoading)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: OutlinedButton.icon(
onPressed: data.isTractionLoading
? null
: () => _refreshTraction(append: true),
icon: data.isTractionLoading
? const SizedBox(
height: 14,
width: 14,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.expand_more),
label: Text(
data.isTractionLoading ? 'Loading...' : 'Load more',
),
Stack(
children: [
if (data.isTractionLoading && traction.isEmpty)
const Padding(
padding: EdgeInsets.symmetric(vertical: 32.0),
child: Center(child: CircularProgressIndicator()),
)
else if (traction.isEmpty)
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'No traction found',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 8),
const Text('Try relaxing the filters or sync again.'),
],
),
),
],
),
)
else
Column(
children: [
...traction.map((loco) => _buildTractionCard(context, loco)),
if (data.tractionHasMore || data.isTractionLoading)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: OutlinedButton.icon(
onPressed: data.isTractionLoading
? null
: () => _refreshTraction(append: true),
icon: data.isTractionLoading
? const SizedBox(
height: 14,
width: 14,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.expand_more),
label: Text(
data.isTractionLoading ? 'Loading...' : 'Load more',
),
),
),
],
),
if (data.isTractionLoading)
Positioned.fill(
child: IgnorePointer(
child: Container(
color: Theme.of(context).colorScheme.surface.withOpacity(0.6),
child: const Center(child: CircularProgressIndicator()),
),
),
),
],
),
],
),
);

View File

@@ -97,10 +97,7 @@ class ApiService {
return body;
}
if (res.statusCode == 401 &&
body is Map<String, dynamic> &&
body['detail'] == 'Not authenticated' &&
_onUnauthorized != null) {
if (res.statusCode == 401 && _onUnauthorized != null) {
await _onUnauthorized!();
}

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
@@ -441,6 +442,30 @@ class DataService extends ChangeNotifier {
return _locoClasses;
}
Future<void> createLocoEvent({
required int locoId,
required String eventDate,
required Map<String, dynamic> values,
required String details,
String eventType = 'other',
}) async {
try {
await api.put(
'/event/new',
{
'loco_id': locoId,
'loco_event_type': eventType,
'loco_event_date': eventDate,
'loco_event_value': jsonEncode(values),
'loco_event_details': details,
},
);
} catch (e) {
debugPrint('Failed to create loco event: $e');
rethrow;
}
}
void clear() {
_homepageStats = null;
_legs = [];

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.1.6+1
version: 0.2.0+1
environment:
sdk: ^3.8.1