From 98e5695f9c77c594a103e9e81128798d41bae46a Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Wed, 01 Apr 2026 18:52:33 +0200
Subject: [PATCH] feat: StoreKit 2 IAP — free tier with 2 sessions and 15min message TTL

---
 lib/screens/chat_screen.dart |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index f51862a..e1aa9db 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -23,9 +23,11 @@
 import '../services/navigate_notifier.dart';
 import '../services/push_service.dart';
 import '../theme/app_theme.dart';
+import '../services/purchase_service.dart';
 import '../widgets/command_bar.dart';
 import '../widgets/input_bar.dart';
 import '../widgets/message_bubble.dart';
+import '../widgets/paywall_banner.dart';
 import '../widgets/session_drawer.dart';
 import '../widgets/status_dot.dart';
 import '../widgets/toast_overlay.dart';
@@ -1332,6 +1334,11 @@
     _sendCommand('create');
   }
 
+  /// Called when the user taps an upgrade CTA in the drawer or paywall banner.
+  Future<void> _handleUpgrade() async {
+    await PurchaseService.instance.purchaseFullAccess();
+  }
+
   void _handleSessionRename(Session session, String newName) {
     _sendCommand('rename', {'sessionId': session.id, 'name': newName});
     final sessions = ref.read(sessionsProvider);
@@ -1385,7 +1392,17 @@
 
   @override
   Widget build(BuildContext context) {
-    final messages = ref.watch(messagesProvider);
+    final allMessages = ref.watch(messagesProvider);
+    final isPro = ref.watch(isProProvider);
+    // Free tier: filter out messages older than 15 minutes on display.
+    // Storage is unchanged — messages reappear if the user later upgrades.
+    final messages = isPro
+        ? allMessages
+        : allMessages.where((m) {
+            final ts = DateTime.fromMillisecondsSinceEpoch(m.timestamp);
+            final age = DateTime.now().difference(ts);
+            return age <= kFreeTierMessageTtl;
+          }).toList();
     final wsStatus = ref.watch(wsStatusProvider);
     final isTyping = ref.watch(isTypingProvider);
     final connectionDetail = ref.watch(connectionDetailProvider);
@@ -1452,15 +1469,18 @@
         sessions: sessions,
         activeSessionId: activeSession?.id,
         unreadCounts: unreadCounts,
+        isPro: ref.watch(isProProvider),
         onSelect: (s) => _switchSession(s.id),
         onRemove: _handleSessionRemove,
         onRename: _handleSessionRename,
         onReorder: _handleSessionReorder,
         onNewSession: _handleNewSession,
         onRefresh: _refreshSessions,
+        onUpgrade: _handleUpgrade,
       ),
       body: Column(
         children: [
+          const PaywallBanner(),
           Expanded(
             child: ListView.builder(
               controller: _scrollController,

--
Gitblit v1.3.1