feat: federnde Übergänge und Animationen, Entwürfe je Raum
- Handy: Chat gleitet federnd über die Chatliste (Liste bleibt aufgebaut, Scrollposition erhalten), beim Zurück wieder hinaus; Liste schon während des Hinausgleitens bedienbar. Mitgliederleiste gleitet herein. - Neue/gesendete Nachrichten ploppen weich auf (nur live, nicht beim Öffnen oder Nachladen), Reaktionen ploppen auf und hüpfen beim Hochzählen, Ungelesen-Zähler hüpft, Scroll-nach-unten-Knopf federt (Handy größer), Antwort-Leiste klappt federnd auf/zu, Senden-Pfeil ploppt, Vollansicht zoomt auf. Alles skaliert mit Einstellung „Animationen“ (0 % = aus). - Fix: Beim Raumwechsel blieben Antwort-Ziel, Auswahl und getippter Text am neuen Raum hängen (Antwort auf Raum A konnte in Raum B rausgehen). Jetzt eigenes Eingabefeld je Raum mit Entwurf im Speicher. - Antwort-Leiste: größeres Schließen-X auf dem Handy. - Tests: test/spring_motion_test.dart, UI-Durchlauf mit Übergängen. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1d0ccfde8b
commit
ae6f651f4c
+34
-13
@@ -17,6 +17,8 @@ import 'package:pyramid/features/chat/chat_view.dart';
|
||||
import 'package:pyramid/features/members/members_panel.dart';
|
||||
import 'package:pyramid/features/rooms/rooms_panel.dart';
|
||||
import 'package:pyramid/features/spaces/spaces_rail.dart';
|
||||
import 'package:pyramid/layout/mobile_page_stack.dart';
|
||||
import 'package:pyramid/widgets/spring_press.dart' show motionDuration;
|
||||
import 'package:pyramid/widgets/search_modal.dart';
|
||||
import 'package:pyramid/widgets/settings_modal.dart';
|
||||
import 'package:pyramid/widgets/share_target_dialog.dart';
|
||||
@@ -335,14 +337,18 @@ class _MobileShell extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final voip = ref.watch(callSignalingProvider);
|
||||
|
||||
Widget body;
|
||||
if (viewMode == ViewMode.voice) {
|
||||
body = const VoiceChannelView();
|
||||
} else if (activeRoomId != null) {
|
||||
body = ChatView(roomId: activeRoomId!);
|
||||
} else {
|
||||
body = const RoomsPanel();
|
||||
}
|
||||
// Die Chatliste bleibt aufgebaut; Chat bzw. Sprachkanal gleiten federnd
|
||||
// darüber (Bernds Wunsch 2026-10-07: mehr Übergänge/Elastizität).
|
||||
final Widget? front = viewMode == ViewMode.voice
|
||||
? const VoiceChannelView()
|
||||
: activeRoomId != null
|
||||
? ChatView(roomId: activeRoomId!)
|
||||
: null;
|
||||
final body = MobilePageStack(
|
||||
base: const RoomsPanel(),
|
||||
front: front,
|
||||
background: pt.bg1,
|
||||
);
|
||||
|
||||
// Symbole der Statusleiste passend zum Theme (hell auf dunkel und umgekehrt).
|
||||
final overlayStyle = (pt.isDark
|
||||
@@ -387,7 +393,12 @@ class _MobileShell extends ConsumerWidget {
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
onTap: () => ref.read(membersPanelOpenProvider.notifier).state = false,
|
||||
child: Container(color: Colors.black.withAlpha(110)),
|
||||
child: TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0, end: 1),
|
||||
duration: motionDuration(context, 220),
|
||||
builder: (_, v, _) =>
|
||||
ColoredBox(color: Colors.black.withAlpha((110 * v).round())),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
@@ -396,10 +407,20 @@ class _MobileShell extends ConsumerWidget {
|
||||
bottom: 0,
|
||||
child: Builder(builder: (ctx) {
|
||||
final w = MediaQuery.sizeOf(ctx).width;
|
||||
return MembersPanel(
|
||||
roomId: activeRoomId!,
|
||||
width: (w * 0.82).clamp(240.0, 320.0),
|
||||
onClose: () => ref.read(membersPanelOpenProvider.notifier).state = false,
|
||||
// Gleitet von rechts herein.
|
||||
return TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 1, end: 0),
|
||||
duration: motionDuration(ctx, 340),
|
||||
curve: Curves.easeOutCubic,
|
||||
builder: (_, v, child) => FractionalTranslation(
|
||||
translation: Offset(v, 0),
|
||||
child: child,
|
||||
),
|
||||
child: MembersPanel(
|
||||
roomId: activeRoomId!,
|
||||
width: (w * 0.82).clamp(240.0, 320.0),
|
||||
onClose: () => ref.read(membersPanelOpenProvider.notifier).state = false,
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user