Skip to content

Commit fdffd43

Browse files
authored
Add deprecation banner to Flutter desktop app (#5110)
## Summary - Adds a red closable banner at the top of the Flutter desktop app with the message: "This app is deprecated. Please migrate to the v2 Desktop app" - "v2 Desktop app" links to https://macos.omi.me - Banner is dismissible via an X button - Shows on all screens (onboarding, home, etc.) since it's placed in `DesktopApp` ## Test plan - [ ] Verify banner appears at the top of the desktop app on launch - [ ] Verify clicking "v2 Desktop app" opens https://macos.omi.me - [ ] Verify clicking the X button dismisses the banner - [ ] Verify mobile layout is unaffected 🤖 Generated with [Claude Code](https://claude.com/claude-code)
2 parents 0a05ae6 + 259a2a0 commit fdffd43

File tree

1 file changed

+86
-28
lines changed

1 file changed

+86
-28
lines changed

app/lib/desktop/desktop_app.dart

Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:firebase_auth/firebase_auth.dart';
66
import 'package:flutter/material.dart';
77

88
import 'package:provider/provider.dart';
9+
import 'package:url_launcher/url_launcher.dart';
910

1011
import 'package:omi/backend/preferences.dart';
1112
import 'package:omi/desktop/pages/desktop_home_wrapper.dart';
@@ -14,38 +15,95 @@ import 'package:omi/pages/persona/persona_profile.dart';
1415
import 'package:omi/providers/auth_provider.dart';
1516

1617
/// @deprecated Use the native Swift macOS app at /desktop/ instead.
17-
class DesktopApp extends StatelessWidget {
18+
class DesktopApp extends StatefulWidget {
1819
const DesktopApp({super.key});
1920

21+
@override
22+
State<DesktopApp> createState() => _DesktopAppState();
23+
}
24+
25+
class _DesktopAppState extends State<DesktopApp> {
26+
bool _showDeprecationBanner = true;
27+
2028
@override
2129
Widget build(BuildContext context) {
22-
return Consumer<AuthenticationProvider>(
23-
builder: (context, authProvider, child) {
24-
// DEBUG: Log routing decision
25-
final isSignedIn = authProvider.isSignedIn();
26-
final onboardingCompleted = SharedPreferencesUtil().onboardingCompleted;
27-
final currentUser = FirebaseAuth.instance.currentUser;
28-
print('DEBUG DesktopApp: isSignedIn=$isSignedIn, onboardingCompleted=$onboardingCompleted');
29-
print('DEBUG DesktopApp: currentUser=${currentUser?.uid}, isAnonymous=${currentUser?.isAnonymous}');
30-
31-
if (isSignedIn) {
32-
if (onboardingCompleted) {
33-
print('DEBUG DesktopApp: -> DesktopHomePageWrapper');
34-
return const DesktopHomePageWrapper();
35-
} else {
36-
print('DEBUG DesktopApp: -> DesktopOnboardingWrapper (not completed)');
37-
return const DesktopOnboardingWrapper();
38-
}
39-
} else if (SharedPreferencesUtil().hasOmiDevice == false &&
40-
SharedPreferencesUtil().hasPersonaCreated &&
41-
SharedPreferencesUtil().verifiedPersonaId != null) {
42-
print('DEBUG DesktopApp: -> PersonaProfilePage');
43-
return const PersonaProfilePage();
44-
} else {
45-
print('DEBUG DesktopApp: -> DesktopOnboardingWrapper (not signed in)');
46-
return const DesktopOnboardingWrapper();
47-
}
48-
},
30+
return Column(
31+
children: [
32+
if (_showDeprecationBanner)
33+
Container(
34+
width: double.infinity,
35+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
36+
color: const Color(0xFFDC2626),
37+
child: Row(
38+
children: [
39+
const Icon(Icons.warning_amber_rounded, color: Colors.white, size: 20),
40+
const SizedBox(width: 10),
41+
Expanded(
42+
child: Row(
43+
children: [
44+
const Text(
45+
'This app is deprecated. Please migrate to the ',
46+
style: TextStyle(color: Colors.white, fontSize: 13, fontWeight: FontWeight.w500),
47+
),
48+
MouseRegion(
49+
cursor: SystemMouseCursors.click,
50+
child: GestureDetector(
51+
onTap: () => launchUrl(Uri.parse('https://macos.omi.me')),
52+
child: const Text(
53+
'v2 Desktop app',
54+
style: TextStyle(
55+
color: Colors.white,
56+
fontSize: 13,
57+
fontWeight: FontWeight.w700,
58+
decoration: TextDecoration.underline,
59+
decorationColor: Colors.white,
60+
),
61+
),
62+
),
63+
),
64+
],
65+
),
66+
),
67+
MouseRegion(
68+
cursor: SystemMouseCursors.click,
69+
child: GestureDetector(
70+
onTap: () => setState(() => _showDeprecationBanner = false),
71+
child: const Icon(Icons.close, color: Colors.white, size: 18),
72+
),
73+
),
74+
],
75+
),
76+
),
77+
Expanded(
78+
child: Consumer<AuthenticationProvider>(
79+
builder: (context, authProvider, child) {
80+
final isSignedIn = authProvider.isSignedIn();
81+
final onboardingCompleted = SharedPreferencesUtil().onboardingCompleted;
82+
final currentUser = FirebaseAuth.instance.currentUser;
83+
print('DEBUG DesktopApp: isSignedIn=$isSignedIn, onboardingCompleted=$onboardingCompleted');
84+
print('DEBUG DesktopApp: currentUser=${currentUser?.uid}, isAnonymous=${currentUser?.isAnonymous}');
85+
86+
if (isSignedIn) {
87+
if (onboardingCompleted) {
88+
print('DEBUG DesktopApp: -> DesktopHomePageWrapper');
89+
return const DesktopHomePageWrapper();
90+
} else {
91+
print('DEBUG DesktopApp: -> DesktopOnboardingWrapper (not completed)');
92+
return const DesktopOnboardingWrapper();
93+
}
94+
} else if (SharedPreferencesUtil().hasOmiDevice == false &&
95+
SharedPreferencesUtil().hasPersonaCreated &&
96+
SharedPreferencesUtil().verifiedPersonaId != null) {
97+
print('DEBUG DesktopApp: -> PersonaProfilePage');
98+
return const PersonaProfilePage();
99+
} else {
100+
print('DEBUG DesktopApp: -> DesktopOnboardingWrapper (not signed in)');
101+
return const DesktopOnboardingWrapper();
102+
}
103+
},
104+
),
105+
),
106+
],
49107
);
50108
}
51109
}

0 commit comments

Comments
 (0)