suggestly_flutter 0.4.0 copy "suggestly_flutter: ^0.4.0" to clipboard
suggestly_flutter: ^0.4.0 copied to clipboard

Themeable dialogs in flutter for Suggestly feedback flows: feature requests, bug reports, and ratings.

suggestly_flutter #

Reusable, fully themeable Material 3 dialogs that capture text input, feature requests, bug reports (including environment metadata and screenshots), and star ratings. Every popup respects accessibility, null safety, and text scaling and can be themed globally or per instance.

Features #

  • SuggestlyFeatureRequestPopup - reproduces the Suggestly feature form with priority and version inputs.
  • SuggestlyBugReportPopup - mirrors the Suggestly web bug report, collecting environment details and up to five validated screenshots via the built-in file picker.
  • SuggestlyRatingPopup - star-based selector with optional comment and custom labels.
  • Shared action model, barrier configuration, autofocus, and semantic labels for all popups.

Getting started #

Add the dependency to your pubspec.yaml (path assumes the monorepo layout):

dependencies:
  suggestly_flutter:
    path: ../suggestly.packages/suggestly_flutter

Then import the package:

import 'package:suggestly_flutter/suggestly_flutter.dart';

Before showing any Suggestly dialogs, initialise the shared client with your API key:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Suggestly.initialize(apiKey: 'YOUR-API-KEY-HERE');
  runApp(const MyApp());
}

Initialisation now validates the API key by fetching your application details. If the key is invalid, a SuggestlyApiException is thrown.

If you do not already store a Suggestly identity for the signed-in customer, call Suggestly.ensureSubmissionIdentity to create or retrieve the user and mint a short-lived submission token:

final SubmissionIdentity identity = await Suggestly.ensureSubmissionIdentity(
  email: currentUser.email,
  name: currentUser.displayName, // Optional; stored only when provided.
);

Keep the returned SubmissionIdentity in memory and pass it to each popup. The SDK automatically refreshes tokens when they expire, so you can reuse the identity across multiple submissions during the same session.

For private applications, reviewer onboarding now happens after the user submits feedback. The backend automatically records the submission, flags the user as a pending reviewer, and emails them a link to accept the invite inside Suggestly—no more manual invite tokens or prompt contexts are required on the client.

Usage #

Feature requests #

final SubmissionIdentity identity = await Suggestly.ensureSubmissionIdentity(
  email: currentUser.email,
  name: currentUser.displayName,
);

final SuggestlyPopupResult<FeedbackSubmissionResult> featureResult =
    await SuggestlyFeatureRequestPopup.show(
  context,
  title: 'Request a feature',
  message: 'Share what would make Suggestly more helpful.',
  identity: identity,
  submitLabel: 'Submit request',
);

if (featureResult.didSubmit) {
  debugPrint('We logged the feature request.');
} else if (featureResult.hasError) {
  debugPrint('Feature request failed: ${featureResult.errorMessage}');
}

Bug reports (with attachments) #

final SuggestlyPopupResult<FeedbackSubmissionResult> bugResult =
    await SuggestlyBugReportPopup.show(
  context,
  title: 'Report a bug',
  message: 'Screenshots are optional but recommended.',
  submitLabel: 'Send report',
  identity: identity,
);

if (bugResult.didSubmit) {
  debugPrint('Thanks for the report!');
} else if (bugResult.hasError) {
  debugPrint('Bug report failed: ${bugResult.errorMessage}');
}

The popup guides users through adding up to five screenshots using the built-in file_selector integration. Attachments are validated for file type and size, renamed deterministically, and uploaded alongside the report.

Ratings #

final SuggestlyPopupResult<FeedbackSubmissionResult> ratingResult =
    await SuggestlyRatingPopup.show(
  context,
  title: 'Rate your experience',
  message: 'Stars help us prioritise improvements.',
  identity: identity,
  ratingLabelBuilder: (value) => '$value / 5',
  submitLabel: 'Submit rating',
);

if (ratingResult.didSubmit) {
  debugPrint('Thanks for the feedback!');
} else if (ratingResult.hasError) {
  debugPrint('Rating failed: ${ratingResult.errorMessage}');
}

Collaborators can submit internal ratings while an application remains in Draft. Once it is live, the popups automatically prevent team members from rating their own product.

Example host app #

An interactive host application lives under example/ so you can exercise the dialogs without wiring them into your product first. Launch it with:

cd suggestly.packages/suggestly_flutter/example
flutter run

Demo mode boots instantly using the bundled in-memory client, and you can toggle eligibility for each popup to validate error paths. Switch to Live mode, paste a real Suggestly API key, and press Initialise to talk to your own backend.

Theming #

Wrap a subtree with TextInputPopupTheme to provide defaults that apply to every popup, or pass themeOverrides to individual dialogs:

TextInputPopupTheme(
  data: TextInputPopupThemeData(
    backgroundColor: Theme.of(context).colorScheme.surface,
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
    contentPadding: const EdgeInsets.fromLTRB(28, 28, 28, 20),
  ),
  child: Builder(
    builder: (context) => FilledButton(
      onPressed: () {
        SuggestlyFeatureRequestPopup.show(
          context,
          title: 'Request a feature',
          message: 'Tell us what would make Suggestly better.',
          identity: identity,
          themeOverrides: const TextInputPopupThemeData(
            primaryButtonStyle: FilledButton.styleFrom(
              minimumSize: Size(140, 40),
            ),
          ),
        );
      },
      child: const Text('Request feature'),
    ),
  ),
);

Additional information #

  • flutter analyze and flutter test run clean.
  • SuggestlyBugReportPopup owns the attachment workflow with file_selector, enforcing the same limits as the Suggestly web app (image formats only, up to five files, 5 MB each).
  • Popups automatically prompt for a missing user name and update the stored Suggestly profile before sending feedback, ensuring submissions include the captured name.
  • Contributions, issues, and suggestions are welcome.

Direct API access #

If you need to interact with the Suggestly service outside the prebuilt dialogs, the Suggestly class exposes the underlying client:

  • Suggestly.ensureSubmissionIdentity normalises email/name input, creates the user if necessary, and issues a signed submission token plus user ID for downstream calls. Reviewer invites are now handled entirely by the backend after submissions, so no additional parameters or dialogs are needed on the client.
  • Suggestly.fetchFeedbackEligibility reads cached eligibility for one or more submission kinds, while Suggestly.ensureFeedbackEligibility refreshes it on demand. Both accept a SubmissionIdentity so the signed submission token (and embedded userId) accompanies every lookup.
  • Suggestly.getApplicationSummary returns the branding metadata used across popups (name, logo, status).
  • Suggestly.submitBugReport, Suggestly.submitFeatureRequest, and Suggestly.submitRating let you send feedback from fully custom flows using the SubmissionIdentity you already issued.
  • Suggestly.dispose clears in-memory caches and closes the internal HTTP client; call it when tearing down long-lived isolates or cleaning up tests.
  • Suggestly.debugOverrideClient accepts a SuggestlyTestingClient (or your own fake) to intercept outbound traffic during automated testing.

User profile lookups and updates are handled automatically within the built-in dialogs and are not part of the public Flutter API surface.

0
likes
150
points
10
downloads

Publisher

unverified uploader

Weekly Downloads

Themeable dialogs in flutter for Suggestly feedback flows: feature requests, bug reports, and ratings.

Homepage
Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

file_selector, flutter, http, shared_preferences, url_launcher

More

Packages that depend on suggestly_flutter