Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 2 additions & 8 deletions .github/actions/generate-assets/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/desktop-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/firebase-hosting-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/firebase-hosting-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/mobile-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/sdk-integration-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
51 changes: 22 additions & 29 deletions lib/services/feedback/feedback_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -80,7 +80,7 @@ class FeedbackService {
'timestamp': DateTime.now().toIso8601String(),

'wallet':
(await GetIt.I<KomodoDefiSdk>().auth.currentUser)?.toJson() ?? 'None'
(await GetIt.I<KomodoDefiSdk>().auth.currentUser)?.toJson() ?? 'None',
};

try {
Expand All @@ -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');
}
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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)
///
Expand All @@ -398,22 +402,18 @@ 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;

const CloudflareFeedbackProvider({
required this.apiKey,
required this.prodEndpoint,
this.testEndpoint = '',
required this.listId,
required this.boardId,
});
Expand All @@ -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;

Expand All @@ -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({
Expand Down
Loading