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>)
|
||||
# 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
|
||||
# Tag v*: analyze + test → build APK → attach to Forgejo Release
|
||||
#
|
||||
# To cut a release:
|
||||
# Create a release via the Forgejo UI on main with a v* tag name.
|
||||
@@ -19,25 +16,7 @@ name: CI & Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
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:
|
||||
analyze:
|
||||
@@ -63,12 +42,6 @@ jobs:
|
||||
build:
|
||||
name: Build release APK
|
||||
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
|
||||
container:
|
||||
image: ghcr.io/cirruslabs/flutter:stable
|
||||
@@ -87,11 +60,7 @@ jobs:
|
||||
- name: Set artifact name
|
||||
id: artifact
|
||||
run: |
|
||||
if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
|
||||
echo "name=fabledapp-dev-${{ github.sha }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "name=fabledapp-${{ github.sha }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
echo "name=fabledapp-${{ github.ref_name }}-${{ github.sha }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload artifact to Forgejo
|
||||
env:
|
||||
@@ -107,7 +76,6 @@ jobs:
|
||||
-F "file=@$APK" || echo "Artifact upload skipped (API may not support this endpoint)."
|
||||
|
||||
- name: Publish Forgejo release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
|
||||
+1
-1
@@ -371,7 +371,7 @@ class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> {
|
||||
|
||||
String _hintForLocation(String location) {
|
||||
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…';
|
||||
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 {
|
||||
try {
|
||||
final response =
|
||||
|
||||
@@ -38,7 +38,7 @@ class NotesApi {
|
||||
'title': title,
|
||||
'body': body,
|
||||
'tags': tags,
|
||||
if (projectId != null) 'project_id': projectId,
|
||||
?'project_id': projectId,
|
||||
});
|
||||
return Note.fromJson(response.data as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
@@ -59,7 +59,7 @@ class NotesApi {
|
||||
'title': title,
|
||||
'body': body,
|
||||
'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>);
|
||||
} on DioException catch (e) {
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProjectsApi {
|
||||
if (description != null && description.isNotEmpty)
|
||||
'description': description,
|
||||
if (goal != null && goal.isNotEmpty) 'goal': goal,
|
||||
if (color != null) 'color': color,
|
||||
?'color': color,
|
||||
});
|
||||
return Project.fromJson(response.data as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
|
||||
@@ -43,8 +43,8 @@ class TasksApi {
|
||||
'status': status.value,
|
||||
'priority': priority.value,
|
||||
'due_date': dueDate?.toIso8601String(),
|
||||
if (projectId != null) 'project_id': projectId,
|
||||
if (parentId != null) 'parent_id': parentId,
|
||||
?'project_id': projectId,
|
||||
?'parent_id': parentId,
|
||||
});
|
||||
return Task.fromJson(response.data as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
|
||||
@@ -72,7 +72,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
_usernameController.text.trim(),
|
||||
_passwordController.text,
|
||||
);
|
||||
if (mounted) context.go(Routes.notes);
|
||||
if (mounted) context.go(Routes.briefing);
|
||||
} on AuthException catch (e) {
|
||||
setState(() => _error = e.message);
|
||||
} on AppException catch (e) {
|
||||
@@ -90,7 +90,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
cookieJar: ref.read(cookieJarProvider),
|
||||
onSuccess: () async {
|
||||
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;
|
||||
final status = ref.read(authProvider);
|
||||
if (status == AuthStatus.authenticated) {
|
||||
context.go(Routes.notes);
|
||||
context.go(Routes.briefing);
|
||||
} else {
|
||||
context.go(Routes.login);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../core/constants.dart';
|
||||
import '../../core/exceptions.dart';
|
||||
import '../../data/api/tasks_api.dart';
|
||||
import '../../data/models/task.dart';
|
||||
import '../../providers/api_client_provider.dart';
|
||||
import '../../providers/tasks_provider.dart';
|
||||
@@ -239,6 +238,7 @@ class _TaskEditScreenState extends ConsumerState<TaskEditScreen> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
DropdownButtonFormField<TaskStatus>(
|
||||
// ignore: deprecated_member_use
|
||||
value: _status,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Status',
|
||||
@@ -253,6 +253,7 @@ class _TaskEditScreenState extends ConsumerState<TaskEditScreen> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
DropdownButtonFormField<TaskPriority>(
|
||||
// ignore: deprecated_member_use
|
||||
value: _priority,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Priority',
|
||||
|
||||
@@ -23,12 +23,13 @@ class ProjectSelector extends ConsumerWidget {
|
||||
|
||||
return projectsAsync.when(
|
||||
loading: () => const LinearProgressIndicator(),
|
||||
error: (_, __) => const SizedBox.shrink(),
|
||||
error: (_, _) => const SizedBox.shrink(),
|
||||
data: (projects) {
|
||||
final active =
|
||||
projects.where((p) => p.status == 'active').toList();
|
||||
|
||||
return DropdownButtonFormField<int?>(
|
||||
// ignore: deprecated_member_use
|
||||
value: value,
|
||||
decoration: decoration ??
|
||||
const InputDecoration(
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ name: fabled_app
|
||||
description: "FabledAssistant mobile client for Android."
|
||||
publish_to: 'none'
|
||||
|
||||
version: 26.03.02+1
|
||||
version: 26.03.12+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.0
|
||||
|
||||
Reference in New Issue
Block a user