Skip to content

Commit baa685d

Browse files
author
Michael Wilkerson-Barker
committed
Updated style; added cloud/edge switch to app bar
1 parent 896efed commit baa685d

12 files changed

+140
-72
lines changed

ios/Podfile.lock

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ PODS:
33
- path_provider_foundation (0.0.1):
44
- Flutter
55
- FlutterMacOS
6-
- realm (1.0.3):
6+
- realm (1.6.1):
7+
- Flutter
8+
- url_launcher_ios (0.0.1):
79
- Flutter
810

911
DEPENDENCIES:
1012
- Flutter (from `Flutter`)
1113
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
1214
- realm (from `.symlinks/plugins/realm/ios`)
15+
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
1316

1417
EXTERNAL SOURCES:
1518
Flutter:
@@ -18,12 +21,15 @@ EXTERNAL SOURCES:
1821
:path: ".symlinks/plugins/path_provider_foundation/darwin"
1922
realm:
2023
:path: ".symlinks/plugins/realm/ios"
24+
url_launcher_ios:
25+
:path: ".symlinks/plugins/url_launcher_ios/ios"
2126

2227
SPEC CHECKSUMS:
2328
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
2429
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
25-
realm: 05551bcd9993706e7acf15163c9fb7d674fcf3b8
30+
realm: 5d10ee70f2daf218914b0496649a2c7f2cbbf7a1
31+
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
2632

2733
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
2834

29-
COCOAPODS: 1.11.3
35+
COCOAPODS: 1.13.0

lib/components/app_bar.dart

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
66
import 'package:flutter_todo/realm/realm_services.dart';
77

88
class TodoAppBar extends StatelessWidget implements PreferredSizeWidget {
9-
TodoAppBar({Key? key}) : super(key: key);
9+
const TodoAppBar({Key? key}) : super(key: key);
1010

1111
@override
1212
Widget build(BuildContext context) {
@@ -15,6 +15,13 @@ class TodoAppBar extends StatelessWidget implements PreferredSizeWidget {
1515
title: const Text('Realm Flutter To-Do'),
1616
automaticallyImplyLeading: false,
1717
actions: <Widget>[
18+
IconButton(
19+
icon: Icon(realmServices.useCloud
20+
? Icons.cloud_circle
21+
: Icons.cloud_circle_outlined),
22+
tooltip: 'Switch Edge/Cloud Connection',
23+
onPressed: realmServices.offlineModeOn ? null : () async => await switchServer(context, realmServices),
24+
),
1825
IconButton(
1926
icon: Icon(realmServices.offlineModeOn
2027
? Icons.wifi_off_rounded
@@ -38,6 +45,12 @@ class TodoAppBar extends StatelessWidget implements PreferredSizeWidget {
3845
Navigator.pushNamed(context, '/login');
3946
}
4047

48+
Future<void> switchServer(BuildContext context, RealmServices realmServices) async {
49+
if (!await realmServices.cloudEdgeSwitch()) {
50+
Navigator.pushNamed(context, '/login');
51+
}
52+
}
53+
4154
@override
4255
Size get preferredSize => Size.fromHeight(kToolbarHeight);
4356
}

lib/components/create_item.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class CreateItemAction extends StatelessWidget {
1212
onPressed: () => showModalBottomSheet(
1313
isScrollControlled: true,
1414
context: context,
15-
builder: (_) => Wrap(children: const [CreateItemForm()]),
15+
builder: (_) => const Wrap(children: [CreateItemForm()]),
1616
));
1717
}
1818
}
@@ -51,9 +51,11 @@ class _CreateItemFormState extends State<CreateItemForm> {
5151
mainAxisAlignment: MainAxisAlignment.center,
5252
mainAxisSize: MainAxisSize.min,
5353
children: <Widget>[
54-
Text("Create a new item", style: theme.headline6),
54+
Text("Create a new item", style: theme.titleLarge),
5555
TextFormField(
5656
controller: _itemEditingController,
57+
decoration: const InputDecoration(
58+
hintText: "Enter item text"),
5759
validator: (value) => (value ?? "").isEmpty ? "Please enter some text" : null,
5860
),
5961
Padding(

lib/components/modify_item.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class _ModifyItemFormState extends State<ModifyItemForm> {
4747
mainAxisAlignment: MainAxisAlignment.center,
4848
mainAxisSize: MainAxisSize.min,
4949
children: <Widget>[
50-
Text("Update your item", style: myTextTheme.headline6),
50+
Text("Update your item", style: myTextTheme.titleLarge),
5151
TextFormField(
5252
controller: _summaryController,
5353
validator: (value) => (value ?? "").isEmpty ? "Please enter some text" : null,

lib/components/widgets.dart

+15-10
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ Widget loginButton(BuildContext context,
5050
Widget templateButton(BuildContext context,
5151
{Color color = Colors.grey,
5252
String text = "button",
53+
Color textColor = Colors.black,
5354
void Function()? onPressed}) {
5455
return Container(
55-
margin: const EdgeInsets.symmetric(horizontal: 10),
56+
margin: const EdgeInsets.symmetric(horizontal: 5),
5657
child: ElevatedButton(
57-
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(color)),
58+
style: ElevatedButton.styleFrom(backgroundColor: color, padding: const EdgeInsets.symmetric(horizontal: 20)),
5859
onPressed: onPressed,
59-
child: Text(text),
60+
child: Text(text, style: TextStyle(color: textColor)),
6061
),
6162
);
6263
}
@@ -75,6 +76,7 @@ Widget okButton(BuildContext context, String text,
7576
context,
7677
color: forestGreenColor,
7778
text: text,
79+
textColor: Colors.white,
7880
onPressed: onPressed,
7981
);
8082
}
@@ -84,6 +86,7 @@ Widget deleteButton(BuildContext context, {void Function()? onPressed}) {
8486
context,
8587
color: darkRedColor,
8688
text: "Delete",
89+
textColor: Colors.white,
8790
onPressed: onPressed,
8891
);
8992
}
@@ -113,13 +116,15 @@ Widget styledFloatingAddButton(BuildContext context,
113116
{required void Function() onPressed}) {
114117
return Padding(
115118
padding: const EdgeInsets.only(bottom: 5),
116-
child: FloatingActionButton(
117-
elevation: 0,
118-
backgroundColor: Colors.white,
119-
onPressed: onPressed,
120-
tooltip: 'Add',
121-
child: Padding(
122-
padding: const EdgeInsets.all(3),
119+
child: Material(
120+
borderRadius: BorderRadius.circular(30.0),
121+
elevation: 5,
122+
shadowColor: Colors.black,
123+
child: FloatingActionButton(
124+
elevation: 0,
125+
backgroundColor: Colors.transparent,
126+
onPressed: onPressed,
127+
tooltip: 'Add',
123128
child: CircleAvatar(
124129
radius: 26,
125130
backgroundColor: Theme.of(context).primaryColor,

lib/main.dart

+5-4
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,21 @@ class App extends StatelessWidget {
3636
Widget build(BuildContext context) {
3737
final String atlasUrl =
3838
Provider.of<Config>(context, listen: false).atlasUrl;
39-
print("To see your data in Atlas, follow this link:$atlasUrl");
39+
print("To see your data in Atlas, follow this link: $atlasUrl");
4040

4141
final currentUser =
4242
Provider.of<RealmServices?>(context, listen: false)?.currentUser;
4343

44-
return WillPopScope(
45-
onWillPop: () async => false,
44+
return PopScope(
45+
canPop: false,
46+
onPopInvoked: (didPop) {},
4647
child: MaterialApp(
4748
title: 'Realm Flutter Todo',
4849
theme: appThemeData(),
4950
initialRoute: currentUser != null ? '/' : '/login',
5051
routes: {
5152
'/': (context) => const HomePage(),
52-
'/login': (context) => LogIn()
53+
'/login': (context) => const LogIn(),
5354
},
5455
),
5556
);

lib/realm/realm_services.dart

+38
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@ import 'package:flutter/material.dart';
55
class RealmServices with ChangeNotifier {
66
static const String queryAllName = "getAllItemsSubscription";
77
static const String queryMyItemsName = "getMyItemsSubscription";
8+
static const String cloudServer = "https://realm.mongodb.com";
9+
static const String edgeServer = "http://172.16.101.112";
10+
static const String email = "[email protected]";
11+
static const String password = "testpass";
812

913
bool showAll = false;
1014
bool offlineModeOn = false;
15+
bool useCloud = true;
1116
bool isWaiting = false;
1217
late Realm realm;
1318
User? currentUser;
1419
App app;
1520

1621
RealmServices(this.app) {
22+
print("RealmServices()");
1723
if (app.currentUser != null || currentUser != app.currentUser) {
1824
currentUser ??= app.currentUser;
1925
realm = Realm(Configuration.flexibleSync(currentUser!, [Item.schema]));
@@ -42,19 +48,51 @@ class RealmServices with ChangeNotifier {
4248
offlineModeOn = !offlineModeOn;
4349
if (offlineModeOn) {
4450
realm.syncSession.pause();
51+
print("OFFLINE");
4552
} else {
4653
try {
4754
isWaiting = true;
4855
notifyListeners();
4956
realm.syncSession.resume();
5057
await updateSubscriptions();
58+
print("ONLINE with server base url: ${app.getBaseUrl()}");
5159
} finally {
5260
isWaiting = false;
5361
}
5462
}
5563
notifyListeners();
5664
}
5765

66+
Future<bool> cloudEdgeSwitch() async {
67+
if (!offlineModeOn && !realm.isClosed) {
68+
useCloud = !useCloud;
69+
try {
70+
isWaiting = true;
71+
realm.syncSession.pause();
72+
final serverUrl = useCloud ? cloudServer : edgeServer;
73+
print("Updating base url to: $serverUrl");
74+
await app.updateBaseUrl(Uri.parse(serverUrl));
75+
User loggedInUser = await app.logIn(Credentials.emailPassword(email, password));
76+
print("Using server base url: ${app.getBaseUrl()}");
77+
if (app.currentUser == null && currentUser != loggedInUser) {
78+
print("User is either null or not the same as the original user");
79+
await close();
80+
return false;
81+
}
82+
realm.syncSession.resume();
83+
} catch (e) {
84+
print("Error occurred while switching servers: $e");
85+
await close();
86+
return false;
87+
} finally {
88+
isWaiting = false;
89+
}
90+
notifyListeners();
91+
}
92+
print("Done switching servers");
93+
return true;
94+
}
95+
5896
Future<void> switchSubscription(bool value) async {
5997
showAll = value;
6098
if (!offlineModeOn) {

lib/screens/homepage.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ class HomePage extends StatelessWidget {
1212
Widget build(BuildContext context) {
1313
return Provider.of<RealmServices?>(context, listen: false) == null
1414
? Container()
15-
: Scaffold(
15+
: const Scaffold(
1616
appBar: TodoAppBar(),
17-
body: const TodoList(),
17+
body: TodoList(),
1818
floatingActionButtonLocation:
1919
FloatingActionButtonLocation.endDocked,
20-
floatingActionButton: const CreateItemAction(),
20+
floatingActionButton: CreateItemAction(),
2121
);
2222
}
2323
}

lib/screens/log_in.dart

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'package:flutter_todo/components/widgets.dart';
55
import 'package:flutter_todo/realm/app_services.dart';
66

77
class LogIn extends StatefulWidget {
8+
const LogIn({super.key});
9+
810
@override
911
_LogInState createState() => _LogInState();
1012
}

lib/theme.dart

+13-11
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@ import 'package:flutter/material.dart';
22

33
appThemeData() {
44
return ThemeData(
5-
primarySwatch: forestGreenColor,
6-
backgroundColor: mistColor,
7-
colorScheme: ColorScheme.fromSwatch(primarySwatch: forestGreenColor),
8-
errorColor: darkRedColor)
5+
colorScheme: ColorScheme.fromSwatch(primarySwatch: forestGreenColor, backgroundColor: mistColor, errorColor: darkRedColor))
96
.copyWith(
107
textButtonTheme: TextButtonThemeData(
118
style: TextButton.styleFrom(
12-
foregroundColor: Colors.blue,
9+
foregroundColor: Colors.white,
1310
),
1411
),
12+
switchTheme: SwitchThemeData(
13+
trackColor: MaterialStateProperty.all<Color>(forestGreenColor),
14+
thumbColor: MaterialStateProperty.all<Color>(Colors.white),
15+
),
1516
checkboxTheme: CheckboxThemeData(
1617
checkColor: MaterialStateProperty.all(Colors.white),
1718
fillColor: MaterialStateProperty.all(forestGreenColor),
1819
),
1920
elevatedButtonTheme: ElevatedButtonThemeData(
2021
style: ButtonStyle(
21-
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
22+
backgroundColor: MaterialStateProperty.all<Color>(forestGreenColor),
23+
overlayColor: MaterialStateProperty.all<Color>(Colors.lightGreen),
2224
textStyle: MaterialStateProperty.all<TextStyle>(
2325
const TextStyle(color: Colors.white)),
2426
),
@@ -29,7 +31,7 @@ appThemeData() {
2931
headerFooterBoxDecoration(BuildContext context, bool isHeader) {
3032
final theme = Theme.of(context);
3133
return BoxDecoration(
32-
color: theme.backgroundColor,
34+
color: theme.colorScheme.background,
3335
border: Border(
3436
top: isHeader
3537
? BorderSide.none
@@ -44,22 +46,22 @@ errorBoxDecoration(BuildContext context) {
4446
final theme = Theme.of(context);
4547
return BoxDecoration(
4648
border: Border.all(color: Colors.black),
47-
color: theme.backgroundColor,
49+
color: theme.colorScheme.background,
4850
borderRadius: const BorderRadius.all(Radius.circular(8)));
4951
}
5052

5153
infoBoxDecoration(BuildContext context) {
5254
final theme = Theme.of(context);
5355
return BoxDecoration(
5456
border: Border.all(color: Colors.black),
55-
color: theme.backgroundColor,
57+
color: theme.colorScheme.background,
5658
borderRadius: const BorderRadius.all(Radius.circular(8)));
5759
}
5860

5961
errorTextStyle(BuildContext context, {bool bold = false}) {
6062
final theme = Theme.of(context);
6163
return TextStyle(
62-
color: theme.errorColor,
64+
color: theme.colorScheme.error,
6365
fontWeight: bold ? FontWeight.bold : FontWeight.normal);
6466
}
6567

@@ -105,5 +107,5 @@ MaterialColor mistColor = MaterialColor(
105107
},
106108
);
107109

108-
Color get darkRedColor => Color.fromARGB(255, 208, 18, 5);
110+
Color get darkRedColor => const Color.fromARGB(255, 208, 18, 5);
109111
Color get lightRedColor => const Color.fromARGB(255, 244, 223, 221);

0 commit comments

Comments
 (0)