luqta_sdk 1.5.2
luqta_sdk: ^1.5.2 copied to clipboard
Official Luqta Flutter SDK for contests, quizzes, rewards & gamification. Preconfigured UI or custom API mode. Level/contest availability checks, profile icon, auto token refresh, and full RTL support.
Changelog #
All notable changes to the Luqta Flutter SDK will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.5.2 - 2026-05-13 #
Fixed #
- Contest detail page: empty levels section.
getContestDetailsProgresssometimes returns levels as a sibling of the contest object (data: { contest: {...}, levels: [...] }) instead of nested inside it. The renderer now normalizes all three known response shapes before parsing, so the levels list always renders. - Contest detail page: stuck "Participate" button.
_buildBottomPlayButtononly checkeduser_progress_of_contest.participant_id, missing the case where progress was reported viaparticipate_progress.participant_id. Now usesContest.hasUserParticipatedso both shapes hide the button correctly. - Level parsing:
Map<dynamic, dynamic>rejection. Level entries arriving as rawMap(without the explicit<String, dynamic>type) are now normalized before parsing instead of being silently dropped.
1.5.1 - 2026-05-13 #
Fixed #
- Private contest: re-prompting for access code after entry. Tapping Participate on a private contest the user had already joined would re-open the access code bottom sheet (and the backend would then reject the second join with "already participated"). The check now relies on
hasUserParticipated(which inspects bothuser_progress_of_contest.participant_idandparticipate_progress.participant_id) and reuses the access code already saved when the detail page was opened, so returning users are never re-prompted.
1.5.0 - 2026-04-30 #
Added #
Level.levelTimeline: New field on theLevelmodel — an end-of-level marker returned by some API endpoints in place ofend_date. Supported as either an ISO-8601 string or a numeric epoch timestamp.- Level availability checks:
LevelDateParser.isLevelAvailable(level)evaluatesstartDate,endDate, andlevelTimeline. The pre-built UI now shows localized "not started yet" / "already ended" alerts instead of silently hiding the action button. - Contest availability checks: Contest detail screen shows a localized alert when a contest has not started or has ended, matching the level check pattern.
levels.completeClientWebhook(levelId, variables): Dedicated method forclient_webhooklevel type — POSTs collected form variables to the/sdk/app/client-webhookendpoint.- Auto user-sync on
initializeUserfailure: WhenLuqtaConfig.userProfileis set andinitializeUserreturnsSDK-USER-001("sync user first"), the SDK automatically callssyncAndInitializeUseronce without surfacing the error to the caller. - Silent token refresh with retry: Expired token errors (
ERROR_FATAL+ "token expired") now trigger a transparent re-initialization followed by a single automatic retry of the failed operation. showProfileIcon(LuqtaConfig): New opt-in flag. Whentrueand the user is initialized, a draggable circular button is rendered (bottom-right). Tapping it opens a bottom sheet with the user's name, contact, total points, and contest statistics pulled from/sdk/app/user/profile.- Profile translations: Added
profile.verified,profile.totalPoints,profile.contestsJoined,profile.completed,profile.inProgress, andprofile.levelsCompletedto bothenandarlocales.
Changed #
Level.fromJson/LevelWithProgress.fromJson:_dateToStringhelper now coercesintanddoubleepoch values to their string representation so downstream date parsers always receive a consistent type.- README: Completely rewritten — full configuration table, level-type reference, date handling guide, availability-check examples, updated API reference, and improved code examples throughout.
Fixed #
- Level completion for
luqta_weebhooktype (backend typo) is now correctly handled alongsideluqta_webhook.
1.4.0 - 2026-03-27 #
Added #
- Zero Storage Mode (
zeroStorage: trueinLuqtaConfig): Privacy-first option — no PII is ever written to any database column in plain text. The client sends plain data +zero_storage: true; the server computes all SHA-256 hashes. Onlysdk_hash_useris populated. LuqtaUser.username: New username identifier inLuqtaUserfor SDK-level user identification.LuqtaUser.uuid: New UUID identifier inLuqtaUser(valid UUID v4 format).UserProfile.uuid: Sync a UUID with the user profile.UserProfile.username: Sync a custom username (sdk_username) with the user profile.UserProfile.userId: Sync an external user ID (sdk_user_id) with the user profile.
Changed #
LuqtaUsernow accepts any of:email,phoneNumber,username,uuid— at least one required. Identifier priority for hash lookup:uuid→username→email→phoneNumber.syncUser()identifier validation now accepts uuid, username, or userId in addition to email/phone.initializeUser()includesusername,uuid, andzero_storagein theX-Userheader when set.- Updated README with zero storage section, new identifier examples, and updated user identification table.
Security #
- Zero storage: even if the database is compromised, no user PII can be recovered — only SHA-256 hashes are stored server-side.
- Re-syncing with
zeroStorage: trueautomatically clears all previously stored PII columns.
1.3.3 - 2026-03-09 #
Fixed #
- Level Description: Level list items now show the actual level description instead of static "Task Description" text
- Image Level Crash: Fixed app crash when opening image level completion screen caused by
Color.withValues()API incompatibility with Flutter versions below 3.27. Replaced allwithValues(alpha:)calls withwithOpacity()for broader Flutter compatibility - QR Scanner Crash: Fixed same
withValues()incompatibility in QR scanner widget - Toast Widget: Fixed
withValues()incompatibility in LuqtaToast widget - Publishing: Fixed package publishing to include lib/ source files
1.3.0 - 2026-01-26 #
Added #
- LuqtaToast: New high z-index toast notification widget that appears above bottom sheets
- Access Code Storage: Automatic caching of private contest access codes for seamless re-entry
- Shimmer Loading: Added shimmer effect to contest cards during loading states
- See All Button: New "See All" button for viewing all contests in vertical list
Changed #
- Backend Error Messages: All API errors now show actual backend error messages (e.g., "Level completion criteria not met") instead of generic translations
- Error Handling: Improved
_getErrorMessage()helper extractsLuqtaError.messagewith proper fallbacks - Private Contest Flow: Enhanced flow - checks local storage first, calls API with access code, shows bottom sheet only if needed
Fixed #
- Fixed error messages showing full
LuqtaError.toString()output instead of just the message - Fixed duplicate error toasts in level completion flow
- Fixed access code validation to properly show backend error messages
Improved #
- README: Completely rewritten with comprehensive documentation for both Preconfigured and Custom modes
- Added complete examples, API reference tables, and widget documentation
1.2.0 - 2026-01-26 #
Added #
- Carousel Layout: New horizontal swipe carousel view for contests (matching Figma design)
- Countdown Timer: Live countdown showing time remaining for each contest
- Info Pills: Display awards count, levels count, and timer on contest cards
- Company Logos: Overlapping company logos in top-left corner of cards
- Page Indicator: Animated dots showing current carousel position
- Segmented Progress Bar: Visual progress indicator with checkmarks for completed levels
- Company Info Section: Horizontal scrolling company cards at bottom of detail screen
- See More/Less: Expandable description text on contest detail
- New translations for carousel UI (enter, awards, levels, left, ended, play, seeMore, seeLess, completeAllLevels)
Changed #
- ContestCard: Complete redesign with full-bleed banner images and gradient overlay
- ContestsScreen: Replaced grid/list view with swipeable carousel
- ContestDetailScreen: Complete redesign matching Figma:
- Banner carousel with back/share buttons
- Title section with expandable description
- Progress section with info pills and segmented progress bar
- Level items with icons, status badges, points, and Play buttons
- Company info carousel at bottom
- Full-width Play button in bottom navigation
- Button Style: Rounded pill-style "Enter" and "Play" buttons matching Figma
- Level Items: New card-based design with status indicators (completed, locked, playable)
1.1.0 - 2026-01-26 #
Added #
- New
LuqtaColorsclass with complete brand color palette from Figma - New
LuqtaSpacingclass with standardized spacing values - New
LuqtaRadiusclass with standardized border radius values - New
LuqtaDecorationshelper class for common decorations - Gradient header component for screens
- Card shadow and elevation helpers
Changed #
- UI Redesign: Updated all UI components to match Luqta Brand Playbook (Figma)
- Theme: Completely redesigned theme with new colors (#7C3AED primary purple)
- ContestCard: New card design with gradient banners, pill badges, stats row, and outlined/filled buttons
- ContestsScreen: New gradient header, improved search bar, better loading states
- Typography: Updated text styles with proper weights and sizes
- Buttons: New button styles matching Figma (outlined for participate, filled for actions)
- Colors: Updated color palette (primary: #7C3AED, secondary: #8B5CF6)
- Default border radius increased to 16px
1.0.4 - 2026-01-24 #
Fixed #
- Fixed Contest model date fields to handle both int (timestamp) and string formats from API
1.0.3 - 2026-01-24 #
Fixed #
- Changed
borderRadiustype fromint?todouble?in BrandingConfig to fix type compatibility with Flutter widgets
1.0.2 - 2026-01-24 #
Fixed #
- Added missing
branding.dartimports to all UI widget files and theme.dart - Fixed
BrandingConfigtype resolution in all UI components
1.0.1 - 2026-01-24 #
Fixed #
- Fixed ambiguous
UserProfileexport by removing duplicate class fromconfig.dart - Fixed
PaginatedDataoperator [] errors inluqta_ui_renderer.dartby accessing.itemsproperty directly - Fixed
contests.participate()signature mismatch by using named parameteraccessCode - Fixed
LuqtaTheme.getThemeData()call to use correct method namegenerateTheme()
Changed #
config.dartnow importsUserProfilefromuser_profile.dartandBrandingConfigfrombranding.dart
1.0.0 - 2026-01-24 #
Added - Core SDK #
- Initial release of Luqta Flutter SDK with 95% Web SDK feature parity
LuqtaClientclass with 73 API methods matching Web SDK- Dual-mode support:
LuqtaMode.custom(API-only) andLuqtaMode.preconfigured(auto-rendered UI) - Auto-render functionality with
render()method for instant UI deployment - Dual authentication system: SDK-level and user-level tokens
Added - UI Components #
ContestsScreen- Browse and filter available contestsContestDetailScreen- View contest details, levels, and prizesContestCard- Reusable contest display cardLevelItem- Level progress indicator with statusQuizWidget- Interactive quiz componentCongratulationDialog- Level/contest completion celebration
Added - Level Completion Widgets #
TextLevelWidget- Text answer submissionQRLevelWidget- QR code scanning with cameraImageLevelWidget- Image capture and uploadLinkLevelWidget- URL submission and validation
Added - Services & APIs #
- Contest management: list, details, participate, levels
- Quiz system: questions, answers, scoring
- Rewards: vouchers, coupons, point redemption
- Profile: user data, history, achievements
- Notifications: real-time updates
Added - Theming & Branding #
LuqtaTheme- Complete theming systemBrandingConfig- Customizable colors, fonts, radii- Material Design 3 integration
- Dark mode support
- RTL/Arabic language support
Added - Security #
- Rate limiting protection
- Request deduplication
- Token validation and refresh
- Secure storage for credentials
Platform Support #
- Android
- iOS
- Web
- macOS
- Windows
- Linux