gvl_comments 1.2.0 copy "gvl_comments: ^1.2.0" to clipboard
gvl_comments: ^1.2.0 copied to clipboard

Drop-in comments widget and comment section for Flutter, with threaded replies, reactions and moderation. Managed backend included, no Firebase setup, just an install key.

Changelog #

All notable changes to the GoodVibesLab Comments Client (Flutter) package will be documented here.

1.2.0 #

Security #

  • Tokens are now bound to the user they were issued for. Switching user without calling invalidateToken() used to reuse the previous user's token for up to an hour, so posts, reactions, reports and profile updates were attributed to the previous user. The SDK now requests a new token whenever the user changes.
  • identify() only sends a profile with a token issued for that same user, so it can no longer overwrite another user's name or avatar.
  • Fixed a ReDoS in link detection. A single crafted 5000-character comment could block the UI thread for about 800 ms on every rebuild, for every viewer of the thread. The pattern is now bounded, with a worst case under 1 ms.
  • TopComment decodes avatars at display size instead of full resolution. Avatar URLs are user-supplied.

Performance #

  • New CommentsKit.listPage() returns CommentsPage{items, nextCursor, hasMore}. lastNextCursor and lastHasMore are deprecated: they were shared by every list and could be overwritten by concurrent loads.
  • commentCount() lookups issued in the same frame, e.g. by every CommentCount in a feed, are merged into one threads/info request. prefetchThreads() splits large requests into chunks of 50, the API limit, where it used to fail with too_many_threads.
  • Moderation settings are cached as the docs described, instead of being refetched on every CommentsList mount.
  • identify() skips a profile that has already been synced.
  • Thread-key validation regexes are compiled once. Link spans are only rebuilt when the text changes.

Added #

  • Quota-aware posting: when a project has used up its monthly comment quota, CommentsKit.post() throws CommentsQuotaExceededException. CommentsList then shows "Comments are paused for now" (localized) with no Retry, and the user's text stays in the composer. Reading, reactions and reports keep working.
  • Comment actions menu (⋯): "Copy" on every comment, and "Report" only on other people's comments when a user is signed in. The menu now sits next to the bubble and no longer covers the text.
  • Report confirmation: a dialog is shown before a comment is reported, so a stray tap no longer flags someone.
  • An optimistic comment shows "Sending…" in place of the timestamp.
  • 6 new localized strings (en/fr/es/de/pt).

Changed #

  • The send button is disabled while the input is empty.
  • composerMaxLines from the theme is honored. The composer used to grow without limit.
  • Relative timestamps refresh every minute ("Just now" no longer sticks).
  • The reaction picker is now a dialog route: Android back, a pop, or predictive back closes it. It used to stay on top of the next screen. The route is named reactionPickerRouteName (gvl_comments/reaction_picker) so RouteObservers such as analytics screen tracking can ignore it, and it keeps the caller's local Theme.
  • Links in comments use the theme's primary color.
  • A failed reaction is rolled back with a message, instead of keeping a reaction the server never recorded.
  • Replying no longer scrolls to the top of the list. Only root comments bring the list back to their position.
  • The "Reply" and reactions targets are easier to tap. Accessibility: the reaction counter reads "N reactions", and the sign-in composer is a button.
  • CommentsList uses listPage().

Fixed #

  • Moderated and reported comments no longer show Reply, the like button or their reaction counts: only the placeholder is left, as with the ⋯ menu.
  • identify() called before the first token (the default CommentsList flow) left an internal in-flight marker stuck. The profile was then never synced for the rest of the session.
  • TopComment and CommentCount discard responses for a previous threadKey (recycled feed items).
  • TopComment now inherits the GvlCommentsThemeData extension and the GvlCommentsTheme ancestor.
  • Links: trailing punctuation is excluded (example.com.), full emails are detected (joe@mail.co.uk), and domains starting with "http" (httpbin.org) can be opened.
  • dispose() clears the singleton. Calling initialize() again closes the previous HTTP client.
  • CommentsList: a slow response for a previous thread or user could overwrite the current one. The reply target and draft were also kept after a thread change, so a reply could be posted in the wrong thread.
  • CommentsList: a reply posted in a collapsed thread (more than 2 replies) was hidden behind "See N more replies". The thread now expands automatically.
  • CommentsList: a pull-to-refresh during a send could drop the new comment or show it twice. The comment is now listed exactly once, including when the refresh response arrives after the post is confirmed.
  • CommentsList: the send button stayed disabled after switching threads during a slow send.
  • CommentsList: threads are only regrouped when the comment list changes, not on every rebuild.
  • CommentsList: an auth error without a message showed the empty state "No comments yet" instead of the error view. In debug, the code pill now shows the code (e.g. invalid_binding).
  • Reply, reaction and report are no longer possible on a comment that hasn't been confirmed yet (local id unknown to the server). The confirmed comment no longer fades in a second time.
  • The "Load previous comments" button is hidden when the API returns no cursor (it did nothing).
  • Fallback date (comments older than 7 days): day and year were swapped (05-03-2026 instead of 2026-03-05), and the date was computed in UTC instead of local time.
  • The "Powered by" link didn't open on Android 11+ (canLaunchUrl without <queries>).

Package #

  • package_info_plus 10.x is accepted (>=9.0.0 <11.0.0). Apps on Flutter 3.38+ can upgrade it, and older apps keep resolving 9.x.
  • The declared minimum is now Flutter 3.19, the real floor already imposed by package_info_plus 9.
  • README: "real-time posting" was misleading. Posting is instant (optimistic UI), but other users' comments appear on refresh. The wording is fixed.

Upgrade notes #

  • lastNextCursor / lastHasMore are deprecated. Use listPage().
  • showCommentReactionPicker now pushes a route: its context needs a Navigator ancestor.
  • With a custom commentItemBuilder, the "⋯" actions button is always shown (Copy is always available). It used to appear only when user reports were enabled.
  • GvlCommentsL10n has 6 new strings. This only matters if you subclass it.

1.1.0 #

Security #

  • Comment body validation is now enforced in CommentsKit.post() — the body is trimmed and rejected (ArgumentError) when empty or longer than maxBodyLength (5000), instead of being sent as-is.
  • User-provided links now require confirmation before opening. Tapping a URL/email in a comment shows a dialog with the target and only opens http, https, and mailto schemes (phishing mitigation).
  • Avatar URLs are validated — only http(s) images are loaded, decoded size is bounded (cacheWidth), and loading failures fall back to initials.
  • Server error bodies are no longer leaked — HttpException and internal error strings are truncated and single-lined; raw response bodies never reach logs or error UIs.
  • HTTPS is enforced for GVL_API_BASE (plain http allowed only for localhost).
  • Debug logging hardened — stray debugPrint calls that could surface server payloads in release now route through CommentsLogger.
  • Identity no longer replayed across users — invalidateToken() now clears any queued identify payload so a previous user's profile can't be re-sent under a new user's token.

Added #

  • Empty state for threads with no comments (icon + localized message), plus an emptyBuilder on CommentsList to customize it.
  • Pull-to-refresh (RefreshIndicator) on the comment list.
  • Loading skeleton replaces the bare full-screen spinner on first load.
  • Composer character limit — the input enforces maxBodyLength with a counter shown as you approach it.
  • Exported CommentReactionsBar / showCommentReactionPicker for use in custom builders.

Changed #

  • Failed sends no longer lose the user's text — on error the composer is restored (text + reply target) and a retry SnackBar is shown, instead of silently dropping the comment.
  • Pagination and refresh failures are surfaced — inline "Retry" on the load-more row and a SnackBar on refresh failure, rather than a silently stopped spinner.
  • Meta row now wraps (timestamp · reply · reactions) instead of overflowing with long names or large text scales.
  • RTL support — reply indentation, the report menu, and branding use directional insets/alignment.
  • Accessibility — interactive meta actions (reply, react, "see more replies", branding) are exposed as semantic buttons with larger tap targets.
  • List items keyed by comment id to avoid state recycling across optimistic inserts.
  • Moderation/reported placeholders in TopComment and the branding label are now localized.

Fixed #

  • Corrected the CommentCount builder signature in the README ((context, count, refresh)).

Note #

  • The API proxy no longer trusts a client-supplied role when issuing SDK tokens — SDK tokens are always end-user tokens (moderator/admin access is dashboard-only). No SDK API change.

1.0.1 #

Added #

  • onCommentPosted callback on CommentsList — called with the confirmed CommentModel after a comment is successfully posted to the server. Useful for analytics, counters, or external state updates.

1.0.0 #

First stable release. The public API is now frozen under semantic versioning.

Breaking changes #

  • CommentModel.status is now a CommentStatus enum. Use comment.commentStatus for type-safe comparisons. The legacy comment.status getter still returns a String for backward compatibility.
  • GvlCommentsStrings.fr() factory removed — use the l10n system (GvlCommentsL10n) for localization instead.

Added #

  • TopComment widget — displays the single most-engaged comment for a thread. Supports full builder customization (builder, loadingBuilder, emptyBuilder, errorBuilder).
  • CommentCount widget — displays the approved comment count for a thread. Reads from cache when prefetchThreads was called (zero latency).
  • CommentsKit.prefetchThreads() — batch-fetches thread info (count + top comment) for multiple threads. Ideal for feed/list performance.
  • CommentsKit.topComment() / CommentsKit.commentCount() — individual API accessors with cache support.
  • ThreadInfo model — holds prefetched count + top comment data.
  • CommentStatus enum (pending, approved, rejected) — replaces string constants.
  • Reaction enum (like, love, laugh, wow, sad, angry) with id, emoji, and emojiFor() helper.
  • LoadMoreButtonBuilder parameter on CommentsList — fully customize the pagination button.
  • Threaded replies (depth 2) with parentId, replyToCommentId, replyToUserId on CommentModel.
  • Localized reaction labels — reaction picker labels (Like, Love, etc.) now go through GvlCommentsL10n.
  • 4 new locales — German (de), Spanish (es), French (fr), Portuguese (pt) alongside English.
  • HTTP request timeout (15 s) on all API calls — prevents indefinite hangs.
  • Body validation constants — CommentsKit.minBodyLength (1) and CommentsKit.maxBodyLength (5000) exposed publicly.
  • topics field in pubspec.yaml for pub.dev discoverability.
  • .pubignore to reduce published package size.

Deprecated #

  • CommentsClient (legacy API) — use CommentsKit instead. Will be removed in 2.0.
  • Comment, CommentsExternalUser, CommentsUserRole, CommentsApiException — use their modern counterparts.
  • CommentModel.statusPending/statusApproved/statusRejected string constants — use CommentStatus enum.

Fixed #

  • iOS podspec had a duplicate Pod::Spec.new block (now consolidated).
  • Android build.gradle version aligned to 1.0.0.
  • Hardened user identification flow (from 0.9.7).

0.9.7 #

Fixed #

  • Hardened user identification flow

0.9.6 #

Security #

  • Added optional strict install key binding for enhanced application security:
    • Android: app signing certificate SHA-256
    • iOS: Team ID
  • Clear and explicit authentication errors when strict binding is enabled and the app signature does not match.
  • Improved protection against API key reuse across unrelated applications.

Added #

  • New production-grade error UI for comments:
    • Retry action
    • Stable debug / support code
    • Optional expandable technical details panel
  • Improved token request headers including platform, package name, and app version.

Improved #

  • SDK initialization and runtime configuration flow.
  • Internal logging and diagnostics for easier production debugging.
  • Android plugin configuration for wider consumer compatibility.
  • More robust handling of authentication and moderation failures (non-fatal where possible).

Internal #

  • Plugin scaffold cleanup and release-ready project structure.
  • iOS podspec metadata updated.
  • iOS privacy manifest (PrivacyInfo.xcprivacy) included.
  • Web compatibility improved via conditional platform imports.

0.9.5 #

  • Added comment reactions (like, love, etc.) with optimistic UI
  • Improved visual polish and interaction feedback
  • Better defaults for spacing, bubble layout, and composer
  • Overall stability and UX improvements

0.9.4 #

  • Example app now runs out-of-the-box with a built-in demo install key

0.9.3 #

  • Added debug-only SDK logs (gvl_comments: prefix)
  • Clear initialization log on startup
  • Improved error diagnostics for missing or invalid install key
  • Safe obfuscation of sensitive values in logs (API key, user id)
  • Better resilience when authentication fails (non-fatal identify)
  • Minor UI improvements

0.9.2 #

  • Fix external link handling (URLs without scheme now open correctly)
  • Improve composer layout and safe-area padding
  • Better avatar rendering
  • Minor visual refinements for comment bubbles and input

0.9.1 #

  • Initial public release on pub.dev
  • Added install key initialization + platform binding headers
  • Included example app (Android + iOS)

0.9.0 — 2025-12-09 #

🚀 Initial Production Release #

  • First production‑ready release of the GVL Comments Flutter SDK.
  • Fully compatible with the GoodVibesLab Comments SaaS platform.
  • Public API validated and stabilized for production apps.

✨ Features #

  • Comment listing with cursor‑based pagination.
  • Comment posting with hydrated server response.
  • Real‑time profile sync: name + avatar resolved automatically from token.
  • Moderation states:
    • pending, approved, rejected
    • is_flagged (AI or user report)
    • Helpers: isReported, isModerated
  • UI widgets:
    • GvlCommentsList (full thread viewer)
    • Built‑in composer with send button
    • Customizable builders: avatar, item, composer, separators
  • Server filtering:
    • Deleted comments never returned
    • AI‑rejected comments replaced by placeholder

🔐 Moderation & Reporting #

  • User report flow with duplicate prevention.
  • AI moderation states surfaced in UI.
  • Auto‑hide, soft‑hide, and hard‑hide behaviors handled by backend + SDK helpers.

🎨 Theming & UI #

  • Complete theming system: GvlCommentsTheme + GvlCommentsThemeData.
  • Presets included: defaults, neutral, compact, card, bubble.
  • Owner and others now aligned left (Facebook‑style layout).
  • Avatar aligned top, not center.
  • Long usernames ellipsized cleanly.
  • New relative timestamps ("just now", "il y a 3 min").
  • Clickable URLs + email detection.
  • Spacing & vertical rhythm refinement for cleaner reading.
  • Light fade/slide animation on comment appear.
  • Optimistic UI state: pending comments appear with opacity until server confirms.

👤 Avatars #

  • Default avatar logic introduced:
    • If avatarUrl → load Image.network
    • On failure → fallback initial
    • If avatarBuilder provided → use custom implementation

🧰 Internal Improvements #

  • Stronger JSON validation & safer parsing.
  • Unified contract with React SDK.
  • Cleaner error handling.
  • Debug logs improved & standardized.
  • Token now exposes plan to allow conditional branding.

🏷️ Branding #

  • Free‑tier apps automatically display
    "Comments powered by GVL Cloud"
    with tappable logo and external link.

Future releases will follow semantic versioning (MAJOR.MINOR.PATCH).

2
likes
140
points
83
downloads
screenshot

Documentation

Documentation
API reference

Publisher

verified publishergoodvibeslab.cloud

Weekly Downloads

Drop-in comments widget and comment section for Flutter, with threaded replies, reactions and moderation. Managed backend included, no Firebase setup, just an install key.

Homepage
Repository (GitHub)
View/report issues

Topics

#comments #comment-section #moderation #reactions #widget

License

unknown (license)

Dependencies

crypto, flutter, flutter_localizations, http, intl, meta, package_info_plus, url_launcher

More

Packages that depend on gvl_comments

Packages that implement gvl_comments