Skip to main content

featurely 0.10.0 copy "featurely: ^0.10.0" to clipboard
featurely: ^0.10.0 copied to clipboard

In-app feedback sheet for the self-hosted Featurely platform: feature requests, issue reports, voting, and comments — themed by your app and localized in 34 languages.

Changelog #

0.10.0 #

  • Web links (http, https and bare www. hosts) in chat messages are underlined and open in the OS when tapped. Other schemes are never linked, and a failed message still retries on tap.

0.9.1 #

  • Fixed the on-screen keyboard covering the chat composer (and the form and comment fields) on iOS and Android: the sheet now keeps its content above the keyboard.

0.9.0 #

macOS: the SDK now runs on macOS 12.0+ with every feature — the feedback list, detail, voting, comments, the submit form with a screenshot, In-App Chat with images, theming, localization, identity, metadata and push notifications. Android and iOS behavior is unchanged.

  • macOS hosts need com.apple.security.network.client (to reach the Featurely server) and com.apple.security.files.user-selected.read-only (for the image open panel) in both DebugProfile.entitlements and Release.entitlements (see the README's macOS section).
  • Push on macOS goes through APNs with your existing .p8 key: the device registers with platform: "ios" and its apnsEnvironment, read from com.apple.developer.aps-environment in the app's embedded.provisionprofile. The macOS app must use the same bundle ID as the iOS app (one APNs topic per project). Add the Push Notifications capability, and forward the token from your AppDelegate (FeaturelyPlugin.didRegisterForRemoteNotifications(deviceToken:)) — FlutterAppDelegate on macOS doesn't forward it to plugins. The plugin becomes the notification-center delegate itself (passing other notifications to the delegate it replaced); hosts that install their own delegate later forward to FeaturelyPlugin.willPresent / FeaturelyPlugin.didReceive. URLs in pushes open with NSWorkspace.
  • Images come from the system open panel; macOS has no camera, so "Take photo" isn't offered. The sheet has no swipe-to-dismiss on macOS; Escape steps back through the sheet's screens, then closes it. No ink ripples on macOS, as on iOS.
  • Submission metadata on macOS: osVersion is macOS 15.1 (patch only when non-zero) and deviceModel the model identifier (Mac16,2).
  • The native code moved from ios/ to a shared darwin/ directory (sharedDarwinSource), still with both Swift Package Manager and CocoaPods support. Nothing to change in iOS apps.
  • The example app has a macOS runner (Swift Package Manager only).

0.8.0 #

Chat images: users can attach up to 4 images to a chat message, from the photo library or the camera, with or without text, and see the images your team sends. Needs a Featurely server that reports limits.chatImagesMax; against older servers the attach button is hidden and nothing changes.

  • iOS hosts that want the camera must add NSCameraUsageDescription to Info.plist (see the README); without a camera "Take photo" is not offered. Android needs nothing unless the app itself declares the CAMERA permission.
  • The composer gains an attach button (photo library, and "Take photo" when the platform reports a camera), a strip of 56×56 thumbnails with remove buttons, and a 4-image cap. Send is enabled with text or at least one image.
  • Every image is re-encoded before upload: oriented, at most 2 048 px on the long edge, EXIF and GPS data stripped; PNG with transparency stays PNG, everything else becomes JPEG (quality 80, then 60 when over attachmentMaxBytes). An image that is still too large is rejected inline. JPEG encoding is pure Dart on a background isolate; no new dependencies.
  • Bubbles show images above the text (one image keeps its aspect ratio; two, three and four form a grid at most 240 dp wide), an "Image removed after the chat closed" placeholder once the server purges them, and "Couldn't load image / Tap to retry" on failure. Tapping an image opens a full-screen viewer with zoom and paging (no share or save).
  • Images are fetched through short-lived signed URLs and cached in memory by attachment id (50 MB LRU). An expired URL (403) reloads the thread once for a fresh one; a purged image (410) shows the placeholder right away.
  • A failed send keeps its images; "Tap to retry" re-sends the same clientMessageId with the same prepared bytes.
  • Wire: a send with images is multipart/form-data (a payload JSON field plus one image part per image, in order); text-only sends stay JSON. Messages decode attachments leniently (an unknown status counts as purged) and config decodes limits.chatImagesMax. New public error code FeaturelyErrorCode.tooManyAttachments.
  • 11 new strings in all 34 locales (sdkChatAttachImage, sdkChatPhotoLibrary, sdkChatTakePhoto, sdkChatRemoveImage, sdkChatImageRemoved, sdkChatImageLoadFailed, sdkChatImageTapToRetry, sdkChatImageTooLarge, sdkChatImageUnsupported, sdkChatImageLimit, sdkChatImagePosition).

0.7.0 #

Push notifications: the package is now a Flutter plugin with native iOS and Android code. It registers the device for pushes your team sends from the Featurely dashboard or your backend, and for Featurely's own "the team replied", "shipped" and public-reply pushes. Needs a Featurely server that reports pushEnabled (push credentials set up under Settings → Push); against older servers, or without credentials, no push calls are made.

  • Upgrading: do a full rebuild after upgrading (not a hot restart), since the package now contains native code. Android apps need minSdk 23.
  • Registration is automatic after init: the device is registered when a token is known and re-registered on any change of token, permission, time zone, locale, app version or opt-out, and at least every 24 h. logout() and account switches unregister the old device ID first and register the same token under the new one. Failures never throw; they go to onError.
  • New Featurely.push (FeaturelyPush): requestPermission({provisional}) (the only way the SDK ever prompts), permission(), optOut() / optIn() / isOptedOut() (per install, survives logout), setTags / getTags (validated client-side, ArgumentError on bad input), setOpenHandler(handler) and, for Android apps that also use firebase_messaging, handleForegroundMessage(data, title:, body:).
  • New navigatorKey parameter on Featurely.init: a tap on a chat reply opens the chat, and "shipped" / "team replied" open the feedback list; a push url opens with the OS. A tap that launches the app is held until init completes; the open handler and URL opening then run without waiting for the navigator (so they work without a navigatorKey too), and only presenting the chat or list waits for it, for up to 30 s.
  • Every tap is saved to a small on-device queue (20 entries) before it is reported, and stays there until the server answers — including while push isn't available yet.
  • FeaturelyApiException.retryAfterHeader: the retry-after header of a 429 as sent (null when absent). A registration 429 without one pauses registration for 60 s.
  • Featurely pushes show in the foreground too — except a chat reply while the chat is on screen, which refreshes the chat right away instead.
  • iOS: set UNUserNotificationCenter.current().delegate = self in your AppDelegate and add the Push Notifications capability; the plugin reads the APNs token and environment itself. Pushes from other senders are left alone.
  • Android: no google-services.json or Google Services plugin needed — the SDK starts its own Firebase app from the config uploaded in Featurely, and falls back to your default Firebase app. Featurely pushes use a "Notifications" channel, localized in all 34 locales (sdkPushChannelName).
  • The iOS plugin ships as a Swift package and as a CocoaPods pod; the example app uses Swift Package Manager only.
  • Dependencies raised to their current releases (http 1.6, http_parser 4.1.2, image_picker 1.2.3, shared_preferences 2.5.5, intl 0.20.2+). The SDK now declares what device_info_plus 13 and package_info_plus 10 already required: Flutter 3.38.1 / Dart 3.10. Android hosts need compileSdk 36 and Android Gradle Plugin 8.9.1 or newer; iOS 15.0.
  • New error codes FeaturelyErrorCode.validationError and FeaturelyErrorCode.tooManyTags; SdkConfig decodes pushEnabled.

0.6.1 #

  • Assistant replies are labeled with the assistant's name only (default "Assistant"); the small "AI" tag is gone. The sdkChatAiTag string is removed.
  • Removed the chat's "Get replies by email" card, along with its PUT /conversation/email call and the six sdkChatEmail* strings. The feedback form's optional email field is unchanged.

0.6.0 #

AI Support Assistant: a Featurely project can let an AI assistant answer chat messages within seconds and hand off to the team when it can't help. Needs a Featurely server with the assistant enabled for the environment; against older servers everything below is ignored and chat works as before.

  • Every chat send now declares assistantCapable: true, so the assistant may answer conversations from this SDK.
  • Assistant replies show the assistant's name and a small "AI" tag. They are plain text (no markdown); numbered lines get a hanging indent.
  • While the assistant is writing, the chat shows "{name} is typing…" and polls every 1.5 s, returning to 5 s when the reply lands or after 60 s.
  • New Featurely.setChatDiagnosticsProvider(provider): a live app-state snapshot sent with each message. The provider gets 1 s; a timeout, a throw, or a result over the limits (4 096 bytes of JSON, 3 levels deep, 200-character strings, 30-item lists) sends the message without it. If the server rejects the snapshot, the message is re-sent once without it.
  • New Featurely.registerChatActions([FeaturelyChatAction(id:, title:)]) and Featurely.setChatActionHandler(handler): the assistant can suggest registered actions, shown as buttons under its reply. The handler returns FeaturelyChatActionResult.stay or .dismiss (closes the chat sheet); a tapped action shows as used for the session.
  • Localized "AI", "Assistant" and "{name} is typing…" strings (sdkChatAiTag, sdkChatAssistantName, sdkChatAssistantTyping) in all 34 locales.

0.5.0 #

  • Refreshed the chat screen. Messages are grouped under day separators (Today, Yesterday, the weekday, then the date), so each message shows only its time. Bubbles have a smaller corner on the sender's side, and team messages no longer carry a visible "Team" label (screen readers still announce it). A message that failed to send shows as a tinted outline bubble.
  • The "Get replies by email" row is now a card above the composer instead of a bar under the header. The composer and send button were resized.
  • Localized "Today" and "Yesterday" strings (sdkChatToday, sdkChatYesterday) in all 34 locales.

0.4.0 #

  • 8 new locales: Bulgarian (bg), Greek (el), Finnish (fi), Indonesian (id), Lithuanian (lt), Romanian (ro), Slovak (sk) and Albanian (sq) — and Traditional Chinese (zh-Hant): 34 in total, matching the Featurely server.
  • Locale resolution now honors script subtags like the server: a Hant script, or a script-less zh with region TW, HK or MO, resolves to zh-Hant (previously zh); zh-Hans-* and other regions stay zh, and unsupported scripts are ignored (pt-Latn-BR → pt-BR).
  • New Featurely.hasUnreadMessages() — true when unreadMessageCount() is above zero, for a simple badge. Never throws; false before init, when chat is unavailable, and on any error.
  • Featurely.showChat(context, initialMessage: text) prefills the chat composer (cursor at the end, field focused). It is never sent automatically; blank text is ignored, it is capped to the 4 000-character limit, and it is applied once per showChat call.
  • Chat metadata: new Featurely.setChatMetadata(map) attaches app-wide context (e.g. plan, app version) to every chat message sent from then on, and Featurely.showChat(context, metadata: map) adds per-presentation context (it wins on key collisions). The team sees it next to the message in the Inbox and the alert email; it is never shown to the user. The SDK trims and caps it to the server's limits (20 entries, 64-character keys, 500-character values) instead of failing the send, and a retried message keeps its original metadata. The field is omitted when empty; servers that predate chat metadata ignore it.

0.3.0 #

In-App Chat: a private one-to-one thread between the device and your team, answered from the dashboard Inbox. Needs a Featurely server that reports chatEnabled in GET /config; older servers keep working with chat hidden.

  • New Featurely.showChat(context) presents the chat as a standalone sheet.
  • New Featurely.unreadMessageCount() returns the number of unread team messages for a host-app badge. It never throws and returns 0 when chat is unavailable.
  • The feedback sheet shows a "Message us" action (when the server supports chat) that opens the chat inside the same sheet.
  • The chat has optimistic sends with tap-to-retry, "Load earlier" history, an optional "Get replies by email" row, 5 s polling while the chat is on screen and the app is in the foreground (paused for 30 s after a 429), and read markers. It also shows the SANDBOX strip and supports RTL.
  • The thread is tied to the device ID, so logout() starts a fresh chat.
  • FeaturelyErrorCode gains invalidMessage and conversationNotFound.
  • 16 new sdk.chat.* strings in all 25 locales.

0.2.3 #

  • Releases are now published to pub.dev automatically from CI when a version tag is pushed. No package changes.

0.2.2 #

  • The header close and filter buttons are larger: 40pt circles (up from 32pt), with the icon scaling up accordingly — a more comfortable tap target.

0.2.1 #

  • The submit form's description hints are now just the question, in all 25 locales: "What should {appName} do?" (Feature) and "What went wrong in {appName}?" (Issue) — the trailing coaching sentences are dropped.

0.2.0 #

Breaking: the environment is no longer derived from the API key prefix. Each project now has a single key (fk_…, always visible in Project Settings); the SDK declares the environment on every request via the X-Featurely-Environment header. Requires a Featurely instance running the single-key migration or later — and older fk_live_…/fk_test_… keys are regenerated by that migration, so update the key when upgrading.

  • Featurely.init accepts environment: (FeaturelyEnvironment, now exported). Default: debug builds → Sandbox, release builds → Live.

  • The key-prefix assert now only checks for fk_; the sandbox strip is driven by the resolved environment instead of the key.

  • Featurely.init accepts onError, an observability hook receiving every API operation that ultimately fails; FeaturelyApiException, FeaturelyErrorCode, and FeaturelyNetworkException are now exported.

  • Comment composer enforces the server's commentMax client-side, matching the title and description fields.

  • Feedback list rows show a one-line description excerpt, and vote boxes announce "N votes" to screen readers.

  • A failed next-page load now renders an inline Retry footer instead of waiting silently for another scroll.

  • The filter sheet's apply button reads "Show 100+ requests" when more results exist beyond the count preview page (new sdkFilterShowResultsOverflow string in all 25 locales).

  • Screenshot re-encodes (e.g. HEIC) are downscaled to at most 2048 px on the longest edge, so large photos no longer produce PNGs that exceed the instance upload limit.

  • Example app: the dark-mode switch now exercises the FeaturelyTheme.brightness override.

0.1.0 #

Initial release.

  • Featurely.init / Featurely.show two-call integration.
  • Feedback list with cursor pagination, pull-to-refresh, filter & sort sheet, and optimistic toggleable voting.
  • Submit form: Feature/Issue, title with live counter, description, optional email, one screenshot (photo library; HEIC transcoded to PNG), auto-captured device metadata, full-screen confirmation.
  • Detail screen with attachment, large vote button, and the public comment thread (Team badges, optimistic composer).
  • Host theming (accent, radius, brightness, font) with fixed status colors; amber SANDBOX strip for fk_test_… keys.
  • Identity linking: login/logout with automatic device-ID rotation and account-switch handling; setPlan.
  • All 25 Featurely locales, RTL included, resolved independently of the host app's locale.
0
likes
160
points
670
downloads

Documentation

API reference

Publisher

verified publishercarpediemcreations.io

Weekly Downloads

In-app feedback sheet for the self-hosted Featurely platform: feature requests, issue reports, voting, and comments — themed by your app and localized in 34 languages.

Repository (GitHub)
View/report issues

Topics

#feedback #feature-requests #bug-report #widget

License

MIT (license)

Dependencies

device_info_plus, flutter, flutter_localizations, http, http_parser, image_picker, intl, package_info_plus, shared_preferences

More

Packages that depend on featurely

Packages that implement featurely