Merge pull request 'v26.03.12.1' (#3) from dev into main
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -1,9 +1,6 @@
|
|||||||
# CI runs first; build only proceeds if analyze and test pass.
|
# CI runs only on release tags.
|
||||||
#
|
#
|
||||||
# Push to dev: analyze + test → build APK → upload artifact (fabledapp-dev-<sha>)
|
# Tag v*: analyze + test → build APK → attach to Forgejo Release
|
||||||
# Push to main: analyze + test only (no build — wait for release tag)
|
|
||||||
# Tag v*: analyze + test → build APK → upload artifact + attach to Forgejo Release
|
|
||||||
# Pull request: analyze + test only
|
|
||||||
#
|
#
|
||||||
# To cut a release:
|
# To cut a release:
|
||||||
# Create a release via the Forgejo UI on main with a v* tag name.
|
# Create a release via the Forgejo UI on main with a v* tag name.
|
||||||
@@ -19,25 +16,7 @@ name: CI & Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main, dev]
|
|
||||||
tags: ["v*"]
|
tags: ["v*"]
|
||||||
paths:
|
|
||||||
- "lib/**"
|
|
||||||
- "test/**"
|
|
||||||
- "pubspec.yaml"
|
|
||||||
- "pubspec.lock"
|
|
||||||
- "analysis_options.yaml"
|
|
||||||
- "android/**"
|
|
||||||
- "assets/**"
|
|
||||||
- ".forgejo/workflows/ci.yml"
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- "lib/**"
|
|
||||||
- "test/**"
|
|
||||||
- "pubspec.yaml"
|
|
||||||
- "pubspec.lock"
|
|
||||||
- "analysis_options.yaml"
|
|
||||||
- ".forgejo/workflows/ci.yml"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
@@ -63,12 +42,6 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
name: Build release APK
|
name: Build release APK
|
||||||
needs: [analyze]
|
needs: [analyze]
|
||||||
# Build on dev branch pushes and version tag pushes only.
|
|
||||||
# main branch pushes run CI for safety but do not build —
|
|
||||||
# the release tag (v*) is the sole trigger for a production APK.
|
|
||||||
if: |
|
|
||||||
github.event_name == 'push' &&
|
|
||||||
(github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/'))
|
|
||||||
runs-on: py3.12-node22
|
runs-on: py3.12-node22
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/cirruslabs/flutter:stable
|
image: ghcr.io/cirruslabs/flutter:stable
|
||||||
@@ -87,11 +60,7 @@ jobs:
|
|||||||
- name: Set artifact name
|
- name: Set artifact name
|
||||||
id: artifact
|
id: artifact
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
|
echo "name=fabledapp-${{ github.ref_name }}-${{ github.sha }}" >> $GITHUB_OUTPUT
|
||||||
echo "name=fabledapp-dev-${{ github.sha }}" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "name=fabledapp-${{ github.sha }}" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Upload artifact to Forgejo
|
- name: Upload artifact to Forgejo
|
||||||
env:
|
env:
|
||||||
@@ -107,7 +76,6 @@ jobs:
|
|||||||
-F "file=@$APK" || echo "Artifact upload skipped (API may not support this endpoint)."
|
-F "file=@$APK" || echo "Artifact upload skipped (API may not support this endpoint)."
|
||||||
|
|
||||||
- name: Publish Forgejo release
|
- name: Publish Forgejo release
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
env:
|
env:
|
||||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
TAG: ${{ github.ref_name }}
|
TAG: ${{ github.ref_name }}
|
||||||
|
|||||||
+1
-1
@@ -371,7 +371,7 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
|
|||||||
|
|
||||||
String _hintForLocation(String location) {
|
String _hintForLocation(String location) {
|
||||||
if (location.startsWith(Routes.library) &&
|
if (location.startsWith(Routes.library) &&
|
||||||
location.contains('tasks')) return 'Add a task…';
|
location.contains('tasks')) { return 'Add a task…'; }
|
||||||
if (location.startsWith(Routes.conversations)) return 'Ask Fabled…';
|
if (location.startsWith(Routes.conversations)) return 'Ask Fabled…';
|
||||||
return 'Capture a note…';
|
return 'Capture a note…';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class BriefingApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GET /api/briefing/conversations/<id>/messages
|
/// GET /api/briefing/conversations/`<id>`/messages
|
||||||
Future<List<Message>> getMessages(int convId) async {
|
Future<List<Message>> getMessages(int convId) async {
|
||||||
try {
|
try {
|
||||||
final response =
|
final response =
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class NotesApi {
|
|||||||
'title': title,
|
'title': title,
|
||||||
'body': body,
|
'body': body,
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
if (projectId != null) 'project_id': projectId,
|
?'project_id': projectId,
|
||||||
});
|
});
|
||||||
return Note.fromJson(response.data as Map<String, dynamic>);
|
return Note.fromJson(response.data as Map<String, dynamic>);
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
@@ -59,7 +59,7 @@ class NotesApi {
|
|||||||
'title': title,
|
'title': title,
|
||||||
'body': body,
|
'body': body,
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
if (clearProject) 'project_id': null else if (projectId != null) 'project_id': projectId,
|
if (clearProject) 'project_id': null else ?'project_id': projectId,
|
||||||
});
|
});
|
||||||
return Note.fromJson(response.data as Map<String, dynamic>);
|
return Note.fromJson(response.data as Map<String, dynamic>);
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class ProjectsApi {
|
|||||||
if (description != null && description.isNotEmpty)
|
if (description != null && description.isNotEmpty)
|
||||||
'description': description,
|
'description': description,
|
||||||
if (goal != null && goal.isNotEmpty) 'goal': goal,
|
if (goal != null && goal.isNotEmpty) 'goal': goal,
|
||||||
if (color != null) 'color': color,
|
?'color': color,
|
||||||
});
|
});
|
||||||
return Project.fromJson(response.data as Map<String, dynamic>);
|
return Project.fromJson(response.data as Map<String, dynamic>);
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ class TasksApi {
|
|||||||
'status': status.value,
|
'status': status.value,
|
||||||
'priority': priority.value,
|
'priority': priority.value,
|
||||||
'due_date': dueDate?.toIso8601String(),
|
'due_date': dueDate?.toIso8601String(),
|
||||||
if (projectId != null) 'project_id': projectId,
|
?'project_id': projectId,
|
||||||
if (parentId != null) 'parent_id': parentId,
|
?'parent_id': parentId,
|
||||||
});
|
});
|
||||||
return Task.fromJson(response.data as Map<String, dynamic>);
|
return Task.fromJson(response.data as Map<String, dynamic>);
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|||||||
_usernameController.text.trim(),
|
_usernameController.text.trim(),
|
||||||
_passwordController.text,
|
_passwordController.text,
|
||||||
);
|
);
|
||||||
if (mounted) context.go(Routes.notes);
|
if (mounted) context.go(Routes.briefing);
|
||||||
} on AuthException catch (e) {
|
} on AuthException catch (e) {
|
||||||
setState(() => _error = e.message);
|
setState(() => _error = e.message);
|
||||||
} on AppException catch (e) {
|
} on AppException catch (e) {
|
||||||
@@ -90,7 +90,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|||||||
cookieJar: ref.read(cookieJarProvider),
|
cookieJar: ref.read(cookieJarProvider),
|
||||||
onSuccess: () async {
|
onSuccess: () async {
|
||||||
await ref.read(authProvider.notifier).verify();
|
await ref.read(authProvider.notifier).verify();
|
||||||
if (mounted) context.go(Routes.notes);
|
if (mounted) context.go(Routes.briefing);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class _SplashScreenState extends ConsumerState<SplashScreen> {
|
|||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
final status = ref.read(authProvider);
|
final status = ref.read(authProvider);
|
||||||
if (status == AuthStatus.authenticated) {
|
if (status == AuthStatus.authenticated) {
|
||||||
context.go(Routes.notes);
|
context.go(Routes.briefing);
|
||||||
} else {
|
} else {
|
||||||
context.go(Routes.login);
|
context.go(Routes.login);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:go_router/go_router.dart';
|
|||||||
|
|
||||||
import '../../core/constants.dart';
|
import '../../core/constants.dart';
|
||||||
import '../../core/exceptions.dart';
|
import '../../core/exceptions.dart';
|
||||||
import '../../data/api/tasks_api.dart';
|
|
||||||
import '../../data/models/task.dart';
|
import '../../data/models/task.dart';
|
||||||
import '../../providers/api_client_provider.dart';
|
import '../../providers/api_client_provider.dart';
|
||||||
import '../../providers/tasks_provider.dart';
|
import '../../providers/tasks_provider.dart';
|
||||||
@@ -239,6 +238,7 @@ class _TaskEditScreenState extends ConsumerState<TaskEditScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
DropdownButtonFormField<TaskStatus>(
|
DropdownButtonFormField<TaskStatus>(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
value: _status,
|
value: _status,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Status',
|
labelText: 'Status',
|
||||||
@@ -253,6 +253,7 @@ class _TaskEditScreenState extends ConsumerState<TaskEditScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
DropdownButtonFormField<TaskPriority>(
|
DropdownButtonFormField<TaskPriority>(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
value: _priority,
|
value: _priority,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Priority',
|
labelText: 'Priority',
|
||||||
|
|||||||
@@ -23,12 +23,13 @@ class ProjectSelector extends ConsumerWidget {
|
|||||||
|
|
||||||
return projectsAsync.when(
|
return projectsAsync.when(
|
||||||
loading: () => const LinearProgressIndicator(),
|
loading: () => const LinearProgressIndicator(),
|
||||||
error: (_, __) => const SizedBox.shrink(),
|
error: (_, _) => const SizedBox.shrink(),
|
||||||
data: (projects) {
|
data: (projects) {
|
||||||
final active =
|
final active =
|
||||||
projects.where((p) => p.status == 'active').toList();
|
projects.where((p) => p.status == 'active').toList();
|
||||||
|
|
||||||
return DropdownButtonFormField<int?>(
|
return DropdownButtonFormField<int?>(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
value: value,
|
value: value,
|
||||||
decoration: decoration ??
|
decoration: decoration ??
|
||||||
const InputDecoration(
|
const InputDecoration(
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ name: fabled_app
|
|||||||
description: "FabledAssistant mobile client for Android."
|
description: "FabledAssistant mobile client for Android."
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 26.03.02+1
|
version: 26.03.12+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.11.0
|
sdk: ^3.11.0
|
||||||
|
|||||||
Reference in New Issue
Block a user