diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 62cfa39..ce8e06b 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -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-) -# 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 }} diff --git a/lib/app.dart b/lib/app.dart index db52833..8da63d7 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -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…'; } diff --git a/lib/data/api/briefing_api.dart b/lib/data/api/briefing_api.dart index 60929c5..c39df8e 100644 --- a/lib/data/api/briefing_api.dart +++ b/lib/data/api/briefing_api.dart @@ -35,7 +35,7 @@ class BriefingApi { } } - /// GET /api/briefing/conversations//messages + /// GET /api/briefing/conversations/``/messages Future> getMessages(int convId) async { try { final response = diff --git a/lib/data/api/notes_api.dart b/lib/data/api/notes_api.dart index 048cdf7..139eb0f 100644 --- a/lib/data/api/notes_api.dart +++ b/lib/data/api/notes_api.dart @@ -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); } 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); } on DioException catch (e) { diff --git a/lib/data/api/projects_api.dart b/lib/data/api/projects_api.dart index c28dbd4..6e7a08b 100644 --- a/lib/data/api/projects_api.dart +++ b/lib/data/api/projects_api.dart @@ -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); } on DioException catch (e) { diff --git a/lib/data/api/tasks_api.dart b/lib/data/api/tasks_api.dart index bb098b8..463202c 100644 --- a/lib/data/api/tasks_api.dart +++ b/lib/data/api/tasks_api.dart @@ -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); } on DioException catch (e) { diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index e5f24cc..b8101d1 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -72,7 +72,7 @@ class _LoginScreenState extends ConsumerState { _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 { cookieJar: ref.read(cookieJarProvider), onSuccess: () async { await ref.read(authProvider.notifier).verify(); - if (mounted) context.go(Routes.notes); + if (mounted) context.go(Routes.briefing); }, ), )); diff --git a/lib/screens/splash/splash_screen.dart b/lib/screens/splash/splash_screen.dart index c911608..9de7075 100644 --- a/lib/screens/splash/splash_screen.dart +++ b/lib/screens/splash/splash_screen.dart @@ -30,7 +30,7 @@ class _SplashScreenState extends ConsumerState { 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); } diff --git a/lib/screens/tasks/task_edit_screen.dart b/lib/screens/tasks/task_edit_screen.dart index 6993ed6..cdab04e 100644 --- a/lib/screens/tasks/task_edit_screen.dart +++ b/lib/screens/tasks/task_edit_screen.dart @@ -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 { ), const SizedBox(height: 16), DropdownButtonFormField( + // ignore: deprecated_member_use value: _status, decoration: const InputDecoration( labelText: 'Status', @@ -253,6 +253,7 @@ class _TaskEditScreenState extends ConsumerState { ), const SizedBox(height: 16), DropdownButtonFormField( + // ignore: deprecated_member_use value: _priority, decoration: const InputDecoration( labelText: 'Priority', diff --git a/lib/widgets/project_selector.dart b/lib/widgets/project_selector.dart index 49ec850..a666c26 100644 --- a/lib/widgets/project_selector.dart +++ b/lib/widgets/project_selector.dart @@ -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( + // ignore: deprecated_member_use value: value, decoration: decoration ?? const InputDecoration( diff --git a/pubspec.yaml b/pubspec.yaml index 654fc03..5c809fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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