feat: initial Pyramid project scaffold
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pyramid/core/router.dart';
|
||||
import 'package:pyramid/core/theme.dart';
|
||||
|
||||
class PyramidApp extends ConsumerWidget {
|
||||
const PyramidApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final router = ref.watch(routerProvider);
|
||||
final colorScheme = ref.watch(colorSchemeProvider);
|
||||
|
||||
return MaterialApp.router(
|
||||
title: 'Pyramid',
|
||||
theme: buildTheme(colorScheme, Brightness.light),
|
||||
darkTheme: buildTheme(colorScheme, Brightness.dark),
|
||||
themeMode: ThemeMode.system,
|
||||
routerConfig: router,
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('de'), Locale('en')],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pyramid/layout/shell_page.dart';
|
||||
import 'package:pyramid/features/rooms/rooms_page.dart';
|
||||
import 'package:pyramid/features/chat/chat_page.dart';
|
||||
import 'package:pyramid/features/settings/settings_page.dart';
|
||||
|
||||
final routerProvider = Provider<GoRouter>((ref) {
|
||||
return GoRouter(
|
||||
initialLocation: '/rooms',
|
||||
routes: [
|
||||
ShellRoute(
|
||||
builder: (context, state, child) => ShellPage(child: child),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/rooms',
|
||||
builder: (context, state) => const RoomsPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat/:roomId',
|
||||
builder: (context, state) =>
|
||||
ChatPage(roomId: state.pathParameters['roomId']!),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/settings',
|
||||
builder: (context, state) => const SettingsPage(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final colorSchemeProvider = Provider<ColorScheme>((ref) {
|
||||
return ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF6B4FA0),
|
||||
brightness: Brightness.light,
|
||||
);
|
||||
});
|
||||
|
||||
ThemeData buildTheme(ColorScheme colorScheme, Brightness brightness) {
|
||||
final scheme = brightness == Brightness.dark
|
||||
? ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF6B4FA0),
|
||||
brightness: Brightness.dark,
|
||||
)
|
||||
: colorScheme;
|
||||
|
||||
return ThemeData(
|
||||
colorScheme: scheme,
|
||||
useMaterial3: true,
|
||||
dividerTheme: const DividerThemeData(space: 1, thickness: 1),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChatPage extends StatelessWidget {
|
||||
final String roomId;
|
||||
const ChatPage({super.key, required this.roomId});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(roomId)),
|
||||
body: const Center(child: Text('Chat')),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RoomsPage extends StatelessWidget {
|
||||
const RoomsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('Rooms')),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingsPage extends StatelessWidget {
|
||||
const SettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('Settings')),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pyramid/features/rooms/rooms_page.dart';
|
||||
|
||||
final sidebarWidthProvider = StateProvider<double>((ref) => 280);
|
||||
|
||||
class PanelLayout extends ConsumerWidget {
|
||||
final Widget mainContent;
|
||||
const PanelLayout({super.key, required this.mainContent});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final sidebarWidth = ref.watch(sidebarWidthProvider);
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: sidebarWidth,
|
||||
child: const RoomsPage(),
|
||||
),
|
||||
_ResizeDivider(
|
||||
onDrag: (delta) {
|
||||
final notifier = ref.read(sidebarWidthProvider.notifier);
|
||||
notifier.state =
|
||||
(notifier.state + delta).clamp(180.0, 480.0);
|
||||
},
|
||||
),
|
||||
Expanded(child: mainContent),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ResizeDivider extends StatelessWidget {
|
||||
final ValueChanged<double> onDrag;
|
||||
const _ResizeDivider({required this.onDrag});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onHorizontalDragUpdate: (d) => onDrag(d.delta.dx),
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.resizeColumn,
|
||||
child: Container(
|
||||
width: 6,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pyramid/layout/panel_layout.dart';
|
||||
|
||||
class ShellPage extends ConsumerWidget {
|
||||
final Widget child;
|
||||
const ShellPage({super.key, required this.child});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isWide = MediaQuery.sizeOf(context).width >= 700;
|
||||
|
||||
return Scaffold(
|
||||
body: isWide
|
||||
? PanelLayout(mainContent: child)
|
||||
: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pyramid/core/app.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(const ProviderScope(child: PyramidApp()));
|
||||
}
|
||||
Reference in New Issue
Block a user