diff --git a/.docker/build.sh b/.docker/build.sh index 46c68aecf7..75a693ef02 100755 --- a/.docker/build.sh +++ b/.docker/build.sh @@ -45,7 +45,7 @@ COMMIT_HASH=$(git rev-parse --short HEAD | cut -c1-7) ENV_ARGS="" ENV_VARS="GITHUB_API_PUBLIC_READONLY_TOKEN TRELLO_API_KEY \ TRELLO_TOKEN TRELLO_BOARD_ID TRELLO_LIST_ID \ -FEEDBACK_API_KEY FEEDBACK_PRODUCTION_URL FEEDBACK_TEST_URL \ +FEEDBACK_API_KEY FEEDBACK_PRODUCTION_URL \ COMMIT_HASH" for VAR in $ENV_VARS; do @@ -57,7 +57,6 @@ for VAR in $ENV_VARS; do TRELLO_LIST_ID) VALUE=$TRELLO_LIST_ID ;; FEEDBACK_API_KEY) VALUE=$FEEDBACK_API_KEY ;; FEEDBACK_PRODUCTION_URL) VALUE=$FEEDBACK_PRODUCTION_URL ;; - FEEDBACK_TEST_URL) VALUE=$FEEDBACK_TEST_URL ;; COMMIT_HASH) VALUE=$COMMIT_HASH ;; *) VALUE= ;; esac diff --git a/.github/actions/generate-assets/action.yml b/.github/actions/generate-assets/action.yml index 4cef01aa57..f6f6d97ad0 100644 --- a/.github/actions/generate-assets/action.yml +++ b/.github/actions/generate-assets/action.yml @@ -37,10 +37,6 @@ inputs: description: "Production URL for Cloudflare feedback service" required: false default: "" - FEEDBACK_TEST_URL: - description: "Test URL for Cloudflare feedback service (debug mode)" - required: false - default: "" runs: using: "composite" @@ -71,7 +67,6 @@ runs: TRELLO_LIST_ID: ${{ inputs.TRELLO_LIST_ID }} FEEDBACK_API_KEY: ${{ inputs.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ inputs.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ inputs.FEEDBACK_TEST_URL }} run: | echo "Running \`flutter build\` to generate assets for the deployment build" @@ -113,14 +108,13 @@ runs: # Add Cloudflare feedback service variables if ALL required values are provided # Note: Cloudflare also needs the Trello board and list IDs to be available - if [ "$HAVE_TRELLO_IDS" = true ] && [ -n "$FEEDBACK_API_KEY" ] && [ -n "$FEEDBACK_PRODUCTION_URL" ] && [ -n "$FEEDBACK_TEST_URL" ]; then + if [ "$HAVE_TRELLO_IDS" = true ] && [ -n "$FEEDBACK_API_KEY" ] && [ -n "$FEEDBACK_PRODUCTION_URL" ]; then echo "Adding Cloudflare feedback service configuration" BUILD_CMD="$BUILD_CMD --dart-define=FEEDBACK_API_KEY=$FEEDBACK_API_KEY" BUILD_CMD="$BUILD_CMD --dart-define=FEEDBACK_PRODUCTION_URL=$FEEDBACK_PRODUCTION_URL" - BUILD_CMD="$BUILD_CMD --dart-define=FEEDBACK_TEST_URL=$FEEDBACK_TEST_URL" else # If any Cloudflare credential is missing, log a message but continue the build - if [ -n "$FEEDBACK_API_KEY" ] || [ -n "$FEEDBACK_PRODUCTION_URL" ] || [ -n "$FEEDBACK_TEST_URL" ] || + if [ -n "$FEEDBACK_API_KEY" ] || [ -n "$FEEDBACK_PRODUCTION_URL" ] || ([ -n "$TRELLO_BOARD_ID" ] || [ -n "$TRELLO_LIST_ID" ]); then echo "Warning: Incomplete Cloudflare feedback credentials provided. All Cloudflare credentials and Trello board/list IDs must be present to include them in the build." fi diff --git a/.github/workflows/desktop-builds.yml b/.github/workflows/desktop-builds.yml index b59be72d36..aad66747fe 100644 --- a/.github/workflows/desktop-builds.yml +++ b/.github/workflows/desktop-builds.yml @@ -78,7 +78,6 @@ jobs: TRELLO_LIST_ID: ${{ secrets.TRELLO_LIST_ID }} FEEDBACK_API_KEY: ${{ secrets.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ secrets.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ secrets.FEEDBACK_TEST_URL }} BUILD_COMMAND: ${{ matrix.build_command }} - name: Build for ${{ matrix.platform }} diff --git a/.github/workflows/firebase-hosting-merge.yml b/.github/workflows/firebase-hosting-merge.yml index d0f68027e0..2f31c24d3a 100644 --- a/.github/workflows/firebase-hosting-merge.yml +++ b/.github/workflows/firebase-hosting-merge.yml @@ -35,7 +35,6 @@ jobs: # Optionally provide feedback service configuration if available FEEDBACK_API_KEY: ${{ secrets.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ secrets.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ secrets.FEEDBACK_TEST_URL }} TRELLO_API_KEY: ${{ secrets.TRELLO_API_KEY }} TRELLO_TOKEN: ${{ secrets.TRELLO_TOKEN }} TRELLO_BOARD_ID: ${{ secrets.TRELLO_BOARD_ID }} diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml index 52b8774ff0..090c1b8272 100644 --- a/.github/workflows/firebase-hosting-pull-request.yml +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -44,7 +44,6 @@ jobs: # Optionally provide feedback service configuration if available FEEDBACK_API_KEY: ${{ secrets.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ secrets.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ secrets.FEEDBACK_TEST_URL }} TRELLO_API_KEY: ${{ secrets.TRELLO_API_KEY }} TRELLO_TOKEN: ${{ secrets.TRELLO_TOKEN }} TRELLO_BOARD_ID: ${{ secrets.TRELLO_BOARD_ID }} diff --git a/.github/workflows/mobile-builds.yml b/.github/workflows/mobile-builds.yml index 0370405de8..71f6942a9f 100644 --- a/.github/workflows/mobile-builds.yml +++ b/.github/workflows/mobile-builds.yml @@ -66,7 +66,6 @@ jobs: TRELLO_LIST_ID: ${{ secrets.TRELLO_LIST_ID }} FEEDBACK_API_KEY: ${{ secrets.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ secrets.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ secrets.FEEDBACK_TEST_URL }} # Flutter build with `--no-pub` flag fails on Android due to a # known regression with the build system in 3.32.5. diff --git a/.github/workflows/sdk-integration-preview.yml b/.github/workflows/sdk-integration-preview.yml index d9ba0192ec..cc0903d93f 100644 --- a/.github/workflows/sdk-integration-preview.yml +++ b/.github/workflows/sdk-integration-preview.yml @@ -131,7 +131,6 @@ jobs: # Optionally provide feedback service configuration if available FEEDBACK_API_KEY: ${{ secrets.FEEDBACK_API_KEY }} FEEDBACK_PRODUCTION_URL: ${{ secrets.FEEDBACK_PRODUCTION_URL }} - FEEDBACK_TEST_URL: ${{ secrets.FEEDBACK_TEST_URL }} TRELLO_API_KEY: ${{ secrets.TRELLO_API_KEY }} TRELLO_TOKEN: ${{ secrets.TRELLO_TOKEN }} TRELLO_BOARD_ID: ${{ secrets.TRELLO_BOARD_ID }} diff --git a/lib/services/feedback/feedback_service.dart b/lib/services/feedback/feedback_service.dart index f5b7c2ba1b..c49dc3b7ce 100644 --- a/lib/services/feedback/feedback_service.dart +++ b/lib/services/feedback/feedback_service.dart @@ -47,8 +47,8 @@ class FeedbackService { final buildMode = kReleaseMode ? 'release' : kDebugMode - ? 'debug' - : (kProfileMode ? 'profile' : 'unknown'); + ? 'debug' + : (kProfileMode ? 'profile' : 'unknown'); // Extract contact information from the extras if provided String? contactMethod; @@ -80,7 +80,7 @@ class FeedbackService { 'timestamp': DateTime.now().toIso8601String(), 'wallet': - (await GetIt.I().auth.currentUser)?.toJson() ?? 'None' + (await GetIt.I().auth.currentUser)?.toJson() ?? 'None', }; try { @@ -95,8 +95,8 @@ class FeedbackService { final altAvailable = provider is TrelloFeedbackProvider ? CloudflareFeedbackProvider.fromEnvironment().isAvailable : provider is CloudflareFeedbackProvider - ? TrelloFeedbackProvider.hasEnvironmentVariables() - : true; + ? TrelloFeedbackProvider.hasEnvironmentVariables() + : true; if (kDebugMode && !altAvailable) { debugPrint('Failed to submit feedback: $e'); } @@ -176,28 +176,32 @@ class FeedbackFormatter { if (appInfo.isNotEmpty) { buffer.writeln(' 📱 App Information:'); appInfo.forEach( - (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value')); + (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value'), + ); buffer.writeln(); } if (deviceInfo.isNotEmpty) { buffer.writeln(' 💻 Device Information:'); deviceInfo.forEach( - (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value')); + (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value'), + ); buffer.writeln(); } if (buildInfo.isNotEmpty) { buffer.writeln(' 🔨 Build Information:'); buildInfo.forEach( - (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value')); + (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value'), + ); buffer.writeln(); } if (walletInfo.isNotEmpty) { buffer.writeln(' 👛 Wallet Information:'); walletInfo.forEach( - (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value')); + (key, value) => buffer.writeln(' • ${_formatKey(key)}: $value'), + ); buffer.writeln(); } @@ -267,8 +271,9 @@ class TrelloFeedbackProvider implements FeedbackProvider { 'TRELLO_LIST_ID': const String.fromEnvironment('TRELLO_LIST_ID'), }; - final missingVars = - requiredVars.entries.where((e) => e.value.isEmpty).toList(); + final missingVars = requiredVars.entries + .where((e) => e.value.isEmpty) + .toList(); if (missingVars.isNotEmpty) { final altAvailable = @@ -382,8 +387,7 @@ class TrelloFeedbackProvider implements FeedbackProvider { /// /// The following environment variables must be set using dart-define: /// FEEDBACK_API_KEY: The API key for the feedback service -/// FEEDBACK_PRODUCTION_URL: The production URL for the feedback API, OR: -/// FEEDBACK_TEST_URL: The test URL for the feedback API to test in debug mode +/// FEEDBACK_PRODUCTION_URL: The production URL for the feedback API /// TRELLO_LIST_ID: The ID of the Trello list where feedback will be sent (shared with TrelloFeedbackProvider) /// TRELLO_BOARD_ID: The ID of the Trello board (shared with TrelloFeedbackProvider) /// @@ -398,14 +402,11 @@ class TrelloFeedbackProvider implements FeedbackProvider { /// /// Example run command (debugging): /// ``` -/// flutter run --dart-define=FEEDBACK_TEST_URL=https://your-test-api-url.com --dart-define=FEEDBACK_API_KEY=your_api_key --dart-define=TRELLO_LIST_ID=your_list_id --dart-define=TRELLO_BOARD_ID=your_board_id +/// flutter run --dart-define=FEEDBACK_API_KEY=your_api_key --dart-define=TRELLO_LIST_ID=your_list_id --dart-define=TRELLO_BOARD_ID=your_board_id /// ``` /// -/// The test URL is hardcoded in the code. -/// class CloudflareFeedbackProvider implements FeedbackProvider { final String apiKey; - final String testEndpoint; final String prodEndpoint; final String listId; final String boardId; @@ -413,7 +414,6 @@ class CloudflareFeedbackProvider implements FeedbackProvider { const CloudflareFeedbackProvider({ required this.apiKey, required this.prodEndpoint, - this.testEndpoint = '', required this.listId, required this.boardId, }); @@ -422,28 +422,24 @@ class CloudflareFeedbackProvider implements FeedbackProvider { /// /// Uses the following environment variables: /// - FEEDBACK_API_KEY: The API key for the feedback service - /// - FEEDBACK_PRODUCTION_URL: The production URL for the feedback API (Only required in release mode) - /// - FEEDBACK_TEST_URL: The test URL for the feedback API (Only required in debug mode) + /// - FEEDBACK_PRODUCTION_URL: The production URL for the feedback API /// - TRELLO_LIST_ID: The ID of the Trello list where feedback will be sent (shared with TrelloFeedbackProvider) /// - TRELLO_BOARD_ID: The ID of the Trello board where feedback will be sent (shared with TrelloFeedbackProvider) static CloudflareFeedbackProvider fromEnvironment() { return CloudflareFeedbackProvider( apiKey: const String.fromEnvironment('FEEDBACK_API_KEY'), prodEndpoint: const String.fromEnvironment('FEEDBACK_PRODUCTION_URL'), - testEndpoint: const String.fromEnvironment('FEEDBACK_TEST_URL'), listId: const String.fromEnvironment('TRELLO_LIST_ID'), boardId: const String.fromEnvironment('TRELLO_BOARD_ID'), ); } - bool get useTestEndpoint => kDebugMode && testEndpoint.isNotEmpty; - - String get _endpoint => useTestEndpoint ? testEndpoint : prodEndpoint; + String get _endpoint => prodEndpoint; @override bool get isAvailable => apiKey.isNotEmpty && - (prodEndpoint.isNotEmpty || (kDebugMode && testEndpoint.isNotEmpty)) && + prodEndpoint.isNotEmpty && listId.isNotEmpty && boardId.isNotEmpty; @@ -465,10 +461,7 @@ class CloudflareFeedbackProvider implements FeedbackProvider { final request = http.MultipartRequest('POST', Uri.parse(_endpoint)); // Set headers including charset - request.headers.addAll({ - 'X-KW-KEY': apiKey, - 'Accept-Charset': 'utf-8', - }); + request.headers.addAll({'X-KW-KEY': apiKey, 'Accept-Charset': 'utf-8'}); // Properly encode all string fields to ensure UTF-8 encoding request.fields.addAll({