mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
Polish mobile inbox and media flows (#4512)
## Summary - make mobile unread state visible with bold channel names, an animated Inbox badge, and swipe-to-toggle Inbox rows - add directional transitions for top-level mobile navigation - let mobile send while media uploads, with cancellable progress UI - normalize iOS and Android video uploads, attach poster frames, and improve native video playback ## Validation - `just mobile-check` - `just mobile-test` - `cargo test -p buzz-media` - Pixel smoke test - iPhone smoke test Desktop background uploads moved to #4522 so the two platforms can be reviewed independently. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: leader <71e9f2c44a6932b6772caaaccda1911d010463c3e2c6c40410b8329956046801@buzz.block.builderlab.xyz> Co-authored-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
@@ -4,6 +4,9 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import 'features/activity/activity_provider.dart';
|
||||
import 'features/activity/inbox_local_state_provider.dart';
|
||||
import 'features/activity/inbox_read_state.dart';
|
||||
import 'features/channels/unread_badge/unread_badge_provider.dart';
|
||||
import 'features/home/home_page.dart';
|
||||
import 'features/pairing/pairing_page.dart';
|
||||
@@ -16,9 +19,32 @@ import 'shared/auth/auth.dart';
|
||||
import 'shared/deeplink/pending_deep_link_provider.dart';
|
||||
import 'shared/emoji/emoji_burst.dart';
|
||||
import 'shared/relay/relay.dart';
|
||||
import 'shared/read_state/read_state_provider.dart';
|
||||
import 'shared/theme/theme.dart';
|
||||
import 'shared/widgets/buzz_loading_indicator.dart';
|
||||
|
||||
/// App-shell projection that joins Activity state for the Home navigation.
|
||||
///
|
||||
/// This belongs at the composition root because it deliberately aggregates
|
||||
/// Activity feature providers for a sibling navigation surface.
|
||||
final _unreadInboxItemCountProvider = Provider<int>((ref) {
|
||||
final readState = ref.watch(readStateProvider);
|
||||
if (!readState.isReady) return 0;
|
||||
|
||||
final localState = ref.watch(inboxLocalStateProvider);
|
||||
final items = ref.watch(inboxItemsProvider);
|
||||
return items
|
||||
.where(
|
||||
(item) => !isInboxItemDone(
|
||||
item,
|
||||
markerOf: readState.effectiveTimestamp,
|
||||
localUnreadOverrides: localState.unreadIds,
|
||||
localDoneSet: localState.doneIds,
|
||||
),
|
||||
)
|
||||
.length;
|
||||
});
|
||||
|
||||
class App extends HookConsumerWidget {
|
||||
const App({super.key});
|
||||
|
||||
@@ -50,11 +76,13 @@ class App extends HookConsumerWidget {
|
||||
|
||||
// Eagerly initialize websocket session and lifecycle observer when
|
||||
// authenticated. These providers connect and manage the websocket.
|
||||
var hasUnreadInbox = false;
|
||||
if (authState.value?.status == AuthStatus.authenticated) {
|
||||
ref.watch(relaySessionProvider);
|
||||
ref.watch(observerRelayProvider);
|
||||
ref.watch(appLifecycleProvider);
|
||||
ref.watch(userStatusCacheProvider);
|
||||
hasUnreadInbox = ref.watch(_unreadInboxItemCountProvider) > 0;
|
||||
}
|
||||
|
||||
// Start listening for buzz:// links immediately (even pre-auth) so a
|
||||
@@ -99,8 +127,11 @@ class App extends HookConsumerWidget {
|
||||
loading: () => const _SplashScreen(),
|
||||
error: (_, _) => const PairingPage(),
|
||||
data: (state) => switch (state.status) {
|
||||
AuthStatus.authenticated => const DeepLinkDispatcher(
|
||||
child: HomePage(settingsPageBuilder: _buildSettingsPage),
|
||||
AuthStatus.authenticated => DeepLinkDispatcher(
|
||||
child: HomePage(
|
||||
settingsPageBuilder: _buildSettingsPage,
|
||||
hasUnreadInbox: hasUnreadInbox,
|
||||
),
|
||||
),
|
||||
_ => const DeepLinkDispatcher(
|
||||
dispatchMessageLinks: false,
|
||||
|
||||
Reference in New Issue
Block a user