Add button bar w/nav to home, notifications, and profile

codemagic-setup
Hank Grabowski 2022-11-18 22:49:11 -05:00
rodzic 37857a96d6
commit 6af1c4f214
9 zmienionych plików z 225 dodań i 13 usunięć

Wyświetl plik

@ -0,0 +1,126 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../routes.dart';
enum NavBarButtons {
home,
notifications,
messages,
contacts,
profile,
}
class AppBottomNavBar extends StatelessWidget {
final NavBarButtons currentButton;
const AppBottomNavBar({super.key, required this.currentButton});
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
onTap: (index) {
final newButton = _indexToButton(index);
if (newButton == currentButton) {
print('same button do nothing');
return;
}
switch (newButton) {
case NavBarButtons.home:
Navigator.of(context).popUntil((route) {
return route.settings.name == ScreenPaths.home;
});
break;
case NavBarButtons.notifications:
context.pushNamed(ScreenPaths.notifications);
break;
case NavBarButtons.messages:
// TODO: Handle this case.
break;
case NavBarButtons.contacts:
// TODO: Handle this case.
break;
case NavBarButtons.profile:
context.pushNamed(ScreenPaths.profile);
break;
}
},
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.black54,
currentIndex: _buttonToIndex(currentButton),
items: _menuItems,
);
}
int _buttonToIndex(NavBarButtons button) {
switch (button) {
case NavBarButtons.home:
return 0;
case NavBarButtons.notifications:
return 1;
case NavBarButtons.messages:
return 2;
case NavBarButtons.contacts:
return 3;
case NavBarButtons.profile:
return 4;
}
}
NavBarButtons _indexToButton(int index) {
if (index == 0) {
return NavBarButtons.home;
}
if (index == 1) {
return NavBarButtons.notifications;
}
if (index == 2) {
return NavBarButtons.messages;
}
if (index == 3) {
return NavBarButtons.contacts;
}
if (index == 4) {
return NavBarButtons.profile;
}
throw ArgumentError('$index has no button type');
}
List<BottomNavigationBarItem> get _menuItems {
return const [
BottomNavigationBarItem(
label: 'Home',
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home_filled),
),
BottomNavigationBarItem(
label: 'Notifications',
icon: Icon(Icons.notifications_none_outlined),
activeIcon: Icon(Icons.notifications),
),
BottomNavigationBarItem(
label: 'Messages',
icon: Icon(Icons.messenger_outline),
activeIcon: Icon(Icons.messenger),
),
BottomNavigationBarItem(
label: 'Contacts',
icon: Icon(Icons.people_outline),
activeIcon: Icon(Icons.people_sharp),
),
BottomNavigationBarItem(
label: 'Profile',
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
),
];
}
}

Wyświetl plik

@ -91,6 +91,9 @@ class _StatusControlState extends State<StatusControl> {
ElapsedDateUtils.epochSecondsToString(entry.backdatedTimestamp),
style: Theme.of(context).textTheme.caption,
),
Text(
item.id,
),
],
),
],

Wyświetl plik

@ -46,7 +46,7 @@ class FriendicaClient {
FutureResult<List<TimelineEntry>, ExecError> getTimeline(
{required TimelineIdentifiers type,
int sinceId = 0,
int limit = 100}) async {
int limit = 20}) async {
final String timelinePath = _typeToTimelinePath(type);
final String timelineQPs = _typeToTimelineQueryParameters(type);
final baseUrl = 'https://$serverName/api/v1/timelines/$timelinePath';
@ -154,7 +154,7 @@ class FriendicaClient {
type: ErrorType.authentication,
message: '${response.statusCode}: ${response.reasonPhrase}'));
}
return Result.ok(response.body);
return Result.ok(utf8.decode(response.bodyBytes));
} catch (e) {
return Result.error(
ExecError(type: ErrorType.localError, message: e.toString()));

Wyświetl plik

@ -6,7 +6,6 @@ import 'package:result_monad/result_monad.dart';
import 'globals.dart';
import 'models/TimelineIdentifiers.dart';
import 'routes.dart';
import 'screens/sign_in.dart';
import 'services/auth_service.dart';
import 'services/connections_manager.dart';
import 'services/entry_manager_service.dart';
@ -86,12 +85,3 @@ class App extends StatelessWidget {
);
}
}
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) {
return SignInScreen();
}
}

Wyświetl plik

@ -3,6 +3,8 @@ import 'package:go_router/go_router.dart';
import 'globals.dart';
import 'screens/editor.dart';
import 'screens/home.dart';
import 'screens/notifications_screen.dart';
import 'screens/profile_screen.dart';
import 'screens/sign_in.dart';
import 'screens/splash.dart';
import 'services/auth_service.dart';
@ -10,6 +12,8 @@ import 'services/auth_service.dart';
class ScreenPaths {
static String splash = '/splash';
static String home = '/';
static String profile = '/profile';
static String notifications = '/notifications';
static String signin = '/signin';
static String signup = '/signup';
static String settings = '/settings';
@ -52,7 +56,24 @@ final appRouter = GoRouter(
GoRoute(
path: ScreenPaths.home,
name: ScreenPaths.home,
builder: (context, state) => HomeScreen(),
pageBuilder: (context, state) => NoTransitionPage(
name: ScreenPaths.home,
child: HomeScreen(),
),
),
GoRoute(
path: ScreenPaths.profile,
name: ScreenPaths.profile,
pageBuilder: (context, state) => NoTransitionPage(
child: ProfileScreen(),
),
),
GoRoute(
path: ScreenPaths.notifications,
name: ScreenPaths.notifications,
pageBuilder: (context, state) => NoTransitionPage(
child: NotificationsScreen(),
),
),
GoRoute(
path: ScreenPaths.splash,

Wyświetl plik

@ -3,11 +3,14 @@ import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import '../controls/app_bottom_nav_bar.dart';
import '../controls/timeline/status_control.dart';
import '../models/TimelineIdentifiers.dart';
import '../services/timeline_manager.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
@ -57,6 +60,9 @@ class _HomeScreenState extends State<HomeScreen> {
Expanded(child: buildTimelineComponent(context, tm))
],
),
bottomNavigationBar: AppBottomNavBar(
currentButton: NavBarButtons.home,
),
);
}

Wyświetl plik

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import '../controls/app_bottom_nav_bar.dart';
class NotificationsScreen extends StatelessWidget {
const NotificationsScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Notifications'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Notifications'),
],
),
),
bottomNavigationBar: AppBottomNavBar(
currentButton: NavBarButtons.notifications,
),
);
}
}

Wyświetl plik

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../controls/app_bottom_nav_bar.dart';
import '../controls/padding.dart';
import '../services/auth_service.dart';
class ProfileScreen extends StatelessWidget {
const ProfileScreen({super.key});
@override
Widget build(BuildContext context) {
final authService = context.watch<AuthService>();
return Scaffold(
appBar: AppBar(
title: Text('Profile'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Profile: ${authService.currentClient.fold(onSuccess: (client) => client.credentials.handle, onError: (error) => 'Error Getting Profile')}'),
VerticalPadding(),
ElevatedButton(
onPressed: () async {
await authService.signOut();
},
child: Text('Sign Out')),
],
),
),
bottomNavigationBar: AppBottomNavBar(
currentButton: NavBarButtons.profile,
),
);
}
}

Wyświetl plik

@ -50,6 +50,7 @@ class SecretsService {
_secureStorage.write(key: _usernameKey, value: credentials.username);
_secureStorage.write(key: _passwordKey, value: credentials.password);
_secureStorage.write(key: _serverNameKey, value: credentials.serverName);
_cachedCredentials = credentials;
return Result.ok(credentials);
} on PlatformException catch (e) {
return Result.error(ExecError(