Changelog
Changelog
Section titled “Changelog”Release history for the Chorki mobile app, newest first.
Entries before iOS 3.0.68 / Android 2.0.91 are not covered — this file starts at commit
9b72fc8b (2026-05-14) and was reconstructed from git history, since there were no
release tags past v0.0.3 and no changelog before this one.
Version numbering
Section titled “Version numbering”The two platforms carry different version numbers and never match:
| Platform | Source of truth | Range covered here |
|---|---|---|
| Android | pubspec.yaml version: → flutter.versionName / flutter.versionCode (android/app/build.gradle:42-43) |
2.0.91 (291) → 2.2.4 (305) |
| iOS | FLUTTER_BUILD_NAME + MARKETING_VERSION hardcoded in ios/Runner.xcodeproj/project.pbxproj, which overrides pubspec (ios/Runner/Info.plist:32 reads $(FLUTTER_BUILD_NAME)) |
3.0.67 → 3.1.77 |
Known quirks:
- iOS
CFBundleVersionis static.ios/Runner/Info.plist:73hardcodes it to3(unchanged since 2024-03-31) andFLUTTER_BUILD_NUMBER = 1in the pbxproj, so the Android build number (+291…) never reaches iOS builds. TestFlight build numbers are set outside the repo. - Force-update is two independent ladders. Because the version schemes diverged,
min_app_version_androidandmin_app_version_iosin the settings API have to be maintained separately (seecheckUpdateinlib/presentation/bloc/splash_screen/splash_screen_bloc.dart). - 3.0.67 never shipped. The BillDesk branch was cut from
cdb1b944, the parent of the commit that set 3.0.67, so it carried 3.0.66 forward and jumped straight to 3.0.68 on merge. - Versions skipped entirely: iOS 3.0.71, 3.0.74, 3.1.74; Android 2.0.92, 2.0.94–96, 2.0.98, 2.1.2–2.2.1 (302).
Adding an entry
Section titled “Adding an entry”Add a new section at the top when bumping versions. Bump both sources — version:
in pubspec.yaml (Android) and the three FLUTTER_BUILD_NAME + MARKETING_VERSION
pairs in the pbxproj (iOS) — and title the section with both numbers. Put native-only
changes under the Android / iOS subsections and everything else under Shared.
Reference the short commit SHA for anything non-obvious.
iOS 3.1.77 · Android 2.2.4 (305) — 2026-07-30
Section titled “iOS 3.1.77 · Android 2.2.4 (305) — 2026-07-30”Targeted subscription-offer deeplinks. (3466d13c, 16069a25, a1f854d5)
Shared
Section titled “Shared”- Added —
/subscribe?id=<a>+<b>shows only the named packages.idis a client-side filter (the API has no such parameter), so it is stripped from the query before the request and applied to the response, preserving the order the ids were listed in and de-duplicating. BecauseUridecodes+in a query to a space, the parser accepts+, commas and whitespace as separators.subscription_screen_bloc.dart. - Changed — targeted links bypass the
conditional_visiblegate. Naming a package by id is how a hidden campaign plan is revealed; the gate still applies to the normal catalog view. - Added —
SubscriptionOfferUnavailablestate for when a deeplinked id matches nothing (deleted, expired, geo-blocked). The screen shows “This offer is no longer available” plus a View all plans button, which re-dispatchesGetPackageswith the newbypassIdFilter: trueflag. The bottom Subscribe bar is hidden in that state — its handler indexes into the (now empty) list. - Fixed — package list stopped at page one.
SubscriptionDataSource.getPackagesnow followslinks.next(capped at 10 pages), since a deeplinked package can sit beyond the API’s 50-per-page first page.subscription_data_source.dart. - Fixed — subscribe deeplink query leaked into later visits.
DeeplinkServicesno longer stashes the subscribe query string in the globaldeeplink_url; it is passed straight to the route. Otherwise anid=filter stuck to every later plain/subscription_screenvisit for the rest of the session. (deeplink_services.dart) - Fixed — stale selection index on a shorter list.
subscriptionIndexresets to 0 when the loaded list is shorter than the previous one. - Added — TVOD package rendering.
Subscription/SubscriptionModelgainedtypeandcontents(newPackageContententity +PackageContentModel). Fortype == 'tvod'— a ticket for a single title, which comes back with an empty description — the row shows the interval in the description slot and the unlocked title’s 16:9 thumbnail below it. The row’s fixedheight: 100.vbecame aminHeightconstraint with anIntrinsicHeightwrapper so only TVOD rows grow. - Added —
AppDecoration.outlinedMenuCard(transparent fill, 1px divider border), now used by the profile, account, download-settings, my-library and preferences screens in place of the filled card. (16069a25) - Profile settings:
Spacerabove the app-version row dropped, 24.v → 14.v spacing. - i18n:
subscription_offer_unavailable,view_all_plans(en + bn). - Tests added:
subscription_data_source_test.dart(pagination),subscription_screen_bloc_test.dart(id parsing, filtering, unavailable state).
iOS 3.1.76 · Android 2.2.3 (304) — 2026-07-23
Section titled “iOS 3.1.76 · Android 2.2.3 (304) — 2026-07-23”Shared
Section titled “Shared”- Fixed — popup notifications could never match a location.
lib/data/models/popup_notification_model.dartreadlocation_classname/location_route_uri/location_templateout of the already-nested location object, where the keys areclassname/route_uri/template, so every location field parsed empty. (0229aefd) - Changed — popups are now location-aware and queued. The full list is cached in
popup_notifications_globalinstead of only firingpopup_list[0]on home load._checkPopupForLocationmatches the current tab’s route URI (trailing slash normalized) on load and on every tab switch, queues matches, and shows them one at a time throughappRouter.navigatorKey.currentContext. The old SharedPreferencesshow_popuponce-per-install suppression was replaced by an in-session_scheduledPopupIdsset.home_screen_bloc.dart,popup_notification_widget.dart. - Added — geo context notifiers
current_city,current_continent,current_timezoneincore/constant/const.dart, populated from the ipinfo response insettings_data_source.dart. - Added —
getDynamicApiV2()onDioApiProviderfor the v2 dynamic API base. - Marktag context / play / purchase payload refinements; the subscription screen’s inline purchase logging (~44 lines) folded into the shared helper.
- i18n: “Have a Redeem code?” → “Redeem Code”.
iOS 3.1.75 · Android 2.2.2 (303) — 2026-07-13
Section titled “iOS 3.1.75 · Android 2.2.2 (303) — 2026-07-13”Domain cutover release. (4600c37d)
Shared
Section titled “Shared”- Changed — chorki.com → chorki.net across
api_static,api_dynamic,ip_info_api,awardsCarnivalUrl, the Marktag tag (mtag-cayk.chorki.net), and the VPN screen’s platform domain. - Refactor:
auth_bottomsheet.dart(~124 lines).
Android
Section titled “Android”autoVerify="true"intent-filters added forchorki.netandwww.chorki.netalongside the existing chorki.com pair.
applinks:chorki.net+applinks:www.chorki.netadded toRunner.entitlements(which was also missing bareapplinks:chorki.com) and toInfo.plist.
iOS 3.0.73 (unchanged) · Android 2.1.1 (301) — 2026-07-09
Section titled “iOS 3.0.73 (unchanged) · Android 2.1.1 (301) — 2026-07-09”Android-only bump — 08f0d018 did not touch the pbxproj, so iOS stayed on 3.0.73.
Shared
Section titled “Shared”- Added —
ChorkiCaptchaWebView(lib/presentation/widgets/auth/chorki_captcha_webview.dart): loads the real Cloudflare-served/captchapage influtter_inappwebviewand forwards the Turnstile token via JS injection. Thecloudflare_turnstilepackage injects inline HTML with a synthetic origin (loadDataWithBaseURL), which defeats HTTP/2 connection coalescing — Turnstile’s randomized*.challenges.cloudflare.comsub-hosts have no public DNS record and then fail withERR_NAME_NOT_RESOLVED, making the widget loop. - Chore — dependency pinning to keep a beta out.
cloudflare_turnstilepinned exact at 3.7.2 andflutter_inappwebview/flutter_inappwebview_androidpinned at 6.1.5 / 1.1.3, because the caret floated onto the 6.2.0-beta line and broke the Android method-channel bridge. - Chore: FVM 3.38.5 → 3.41.8;
marktag^2.0.2 → ^2.0.3. - Docs:
docs/api/— Postman collection, environment file, and README.
iOS 3.0.73 · Android 2.1.0 (300) — 2026-06-25
Section titled “iOS 3.0.73 · Android 2.1.0 (300) — 2026-06-25”Pure analytics-instrumentation release. (f45f53aa)
Shared
Section titled “Shared”- Added — three shared Marktag modules, centralizing payloads that were duplicated
across firing sites:
core/utils/marktag_context.dart—buildMarktagUserContext()assembling chorkiId, country / IP, a compact device descriptor (returns{}on failure so an event is never blocked), and a coarsesubscriptionStatus()ofnone/expired/active.core/utils/marktag_play.dart—logMarktagPlay()with content-type mapping, resume position, and genre/cast/age falling back to the parent series for episodes lacking their own metadata.core/utils/marktag_purchase.dart—logMarktagPurchase()unified across SVOD web, SVOD IAP and TVOD web, and across success / failed / canceled, addingpurchase_status,sub_type,payment_gateway,package_idwhile keeping the existingvalue/currency/plan_name/plan_duration/methodfields.
- Refactor: the firing sites in
user_auth_bloc,in_app_purchase_bloc,subscription_screen,web_view,single_content_screen,video_player_screenall switched to those helpers.
iOS 3.0.72 · Android 2.0.99 (299) — 2026-06-22
Section titled “iOS 3.0.72 · Android 2.0.99 (299) — 2026-06-22”Shared
Section titled “Shared”- Fixed — Marktag Signup events were both duplicated and lost. (
5930e31f)- The email signup flag moved from an in-memory
boolto SharedPreferences (marktag_email_signup_pending) so it survives an app kill between OTP and SetPassword. Forgot-password shares the samePasswordSetpath, so this flag is the only way to tell a signup from a reset. - Phone/social signups are detected by a missing profile, which recurs on repeat logins
before profile setup; now guarded by a persisted per-account key
(
marktag_signup_logged_$userId) via a new_logSignupOnce(). AppInstallis no longer burned on an offline first launch — it checksInternetConnectionCheckerfirst and retries next launch, since the SDK is fire-and-forget and swallows delivery failures.
- The email signup flag moved from an in-memory
- Added — Marktag Purchase event on IAP verify success, with plan details.
VerifyPurchasenow carries theSubscription;subscription_screen.dartcaptures the plan at Subscribe-tap time because the verify response contains no plan data. (0055dd5a) - Added — Tools section:
toolsUrl/toolsDeeplinkPath, a/toolsdeep-link branch indeeplink_services.dart, a Tools card in the preferences screen, and “Tools” strings in both locales. (0055dd5a) - Added — notification badge count in profile settings, with its own bloc.
(
0055dd5a) - Fixed — hidden subscription packages were shown to everyone. A
visibilityfield was added toSubscriptionModel/Subscriptionand the subscription screen now filters on it unless a query param opts in (hiddenSubscriptionPackageIdconst). (0055dd5a,34a09c6d) - Added —
logMarktagEvent()(core/utils/marktag_logger.dart):debugPrints every event’s full payload as one grep-able[MARKTAG]line before forwarding to the SDK. UsesdebugPrintrather thandart:developer’slog, which drops/truncates long lines in theflutter runconsole. (34a09c6d) - Refactor:
web_view.dartrestructured (~313 lines). (5930e31f) - Chore:
device_info_plus,share_plus,package_info_plusupgraded; SDK constraints moved to Dart 3.10.0 / Flutter 3.38.1; FVM pin updated. (0055dd5a) - i18n: “My Account” → “Account Settings”, “Account” → “My Account”, “App Version” → “V.”
iOS 3.0.70 · Android 2.0.97 (297) — 2026-06-14
Section titled “iOS 3.0.70 · Android 2.0.97 (297) — 2026-06-14”The largest release in this range — the offline-download subsystem was rewritten.
Shared
Section titled “Shared”- Added — HLS download pipeline, replacing the old downloader. (
da4c2510) Newlib/data/services/hls/:download_orchestrator.dart,download_task_factory.dart,hls_manifest_parser.dart,local_playlist_writer.dart,asset_progress_tracker.dart, plusdownload_manager_impl.dart,content_entity_serde.dart, newDownloadRecord/DownloadStatusV2entities, aDownloadManagerinterface, and aDownloadRowWatcherwidget. Removeddownload_services.dart(983 lines),download_local_data_source.dart,download_repository_impl.dart,get_downloads.dart.CacheContentEntityreshaped (Hive adapter regenerated). - Added — download progress notifications. (
7ad15874)download_progress_notifier.dart,flutter_local_notifications+permission_handler, and running / paused / error / complete / interrupted / multi-item strings inintl_en.arb+intl_bn.arb. - Added — download protection tip (
download_protection_tip.dart): one-time dialog for aggressive-OEM battery managers, with a deep link into device settings. - Added — range-request support in the local playback server so seeking works on
offline HLS.
lib/domain/services/local_server.dartgainedRangehandling, extra media MIME types, and guaranteed response closure on exceptions; newLocalPlaybackServerController. (1d2f0af4) - Added — settings restructure.
profile_settings.dartsplit intomy_library_screen.dart,account_screen.dart,preferences_screen.dart; the oldpreference_screen.dartdeleted. New strings: My Library, Account, Preferences, Support & About, Contact Us, Share App, App Version. (1d2f0af4) - Added — profile settings redesign. (
7ad15874) Profile avatar list with add-profile, menu cards, bottom action row (share / rate / help / call support), version display and logout. - Added — Awards / Carnival entry point, gated on a new
awards_enabledRemote Config flag, with an/awardsdeep link that shows the auth sheet first and drops the pending link if the user closes it without logging in.deeplink_services.dart,remote_config_service.dart,Award_Icon.svg. (7ad15874) - Fixed — Hive downloads migration could brick startup or corrupt progress.
(
9768c216)- A failed box wipe no longer persists the schema version, so the migration retries
next launch instead of being skipped forever (the old
CacheContentEntitysharestypeId1 with an incompatible field map, which throws on read). - Legacy download dirs are now detected via bare
.ts/.m4ssegments as well asmaster.m3u8, so partial old downloads get cleaned — stale segments were inflating the new tracker’s disk count and finalizing re-downloads prematurely. _initHivedeletes and recreates an unreadabledownloadsbox instead of wedging every app start.
- A failed box wipe no longer persists the schema version, so the migration retries
next launch instead of being skipped forever (the old
- Fixed — account screen device card now routes to the purchase screen instead of the
devices URL; unused purchase card removed from My Library. (
7ad15874)
Android
Section titled “Android”DownloadForegroundService.kt(new, 165 lines) +MainActivity.ktmethod-channel plumbing (+123),FOREGROUND_SERVICE_DATA_SYNCand notification permissions, service registration,values/+values-bn/strings.xml. (7ad15874)- Removed the unused
FOREGROUND_SERVICE_MEDIA_PLAYBACKpermission. (9768c216)
AppDelegate.swift+Info.plistentries for the notification/download path; one staleInfo.plistkey removed inda4c2510.
iOS 3.0.69 · Android 2.0.93 (293) — 2026-05-24
Section titled “iOS 3.0.69 · Android 2.0.93 (293) — 2026-05-24”Shared
Section titled “Shared”- Added — geo-targeted subscription bottomsheet, driven by a JSON Firebase Remote
Config key
subscription_geo_bottomsheet. NewSubscriptionGeoBottomsheetConfigentity +RemoteConfigService.getSubscriptionGeoBottomsheetConfig()(falls back to.disabled()when RC is unavailable), newsubscription_geo_bottomsheet.dartwidget, wired intosubscription_screen.dartandsingle_content_screen.dart. (ca790e3c, UI polish in421133b8, spacing inc4ee8cea) - Fixed — trailer controls lifecycle. The player status listener was never removed
when the controller instance swapped, and
setStatecould run after dispose.lib/presentation/widgets/player/trailer_controls.dartreworked (~283 lines), addeddispose()andmountedguards. (ca790e3c) - Fixed — UPI links opened via
target=_blankwere still lost. Added anonCreateWindowhandler plusjavaScriptCanOpenWindowsAutomatically: true, widened the regex from(upi)to(upi|intent), and added diagnostic logging whencanLaunchUrlreturns false. (c4ee8cea) - New assets
announcement.png,danger_triangle.svg+image_constant.dartentries. - Tooling:
.vscode/launch.jsonrun configurations added. (421133b8)
iOS 3.0.68 · Android 2.0.91 (291) — 2026-05-19
Section titled “iOS 3.0.68 · Android 2.0.91 (291) — 2026-05-19”Merge 458bac61 of feature/billdesk-upi-intent-webview.
Shared
Section titled “Shared”- Fixed — BillDesk UPI handoff was silently failing. Non-http URL interception in
InAppWebViewnever launchedupi:///intent://links, so UPI payments dead-ended.shouldOverrideUrlLoadinginlib/presentation/pages/in_app_view/web_view.dartnow hands off tolaunchUrl(externalApplication)(41631f3a), gated on a doc-verbatim(upi)regex so other non-http schemes fall through toALLOW(f4342f86). - Added — Sentry. Initialized only when
!kDebugModeandSENTRY_DSNis non-empty; Sentry Dio interceptor added to everyDioApiProviderclient. DSN / environment / release / sample-rate areString.fromEnvironmentso CI can override per build.lib/main.dart,lib/core/network/dio_api_provider.dart. (27d04aa3) - Fixed — force-update prompt used the wrong minimum version on iOS.
checkUpdateinsplash_screen_bloc.dartparsedmin_app_version_androidon both platforms; now selectsmin_app_version_ioson iOS. (ab987523)
Android
Section titled “Android”<queries>entries inAndroidManifest.xmlsocanLaunchUrlcan resolve UPI apps under Android 11+ package visibility.
LSApplicationQueriesSchemesentries inInfo.plistfor the same reason.