Repository navigation
Expand file tree
/
Copy pathapp.dart
More file actions
171 lines (155 loc) · 6.05 KB
/
Copy pathapp.dart
File metadata and controls
171 lines (155 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import 'package:flutter/material.dart';
import '../model/narrow.dart';
import 'about_zulip.dart';
import 'login.dart';
import 'message_list.dart';
import 'recent_dm_conversations.dart';
import 'store.dart';
class ZulipApp extends StatelessWidget {
const ZulipApp({super.key});
@override
Widget build(BuildContext context) {
final theme = ThemeData(
useMaterial3: false, // TODO(#225) fix things and switch to true
// This applies Material 3's color system to produce a palette of
// appropriately matching and contrasting colors for use in a UI.
// The Zulip brand color is a starting point, but doesn't end up as
// one that's directly used. (After all, we didn't design it for that
// purpose; we designed a logo.) See docs:
// https://api.flutter.dev/flutter/material/ColorScheme/ColorScheme.fromSeed.html
// Or try this tool to see the whole palette:
// https://m3.material.io/theme-builder#/custom
colorScheme: ColorScheme.fromSeed(seedColor: kZulipBrandColor));
return GlobalStoreWidget(
child: MaterialApp(
title: 'Zulip',
theme: theme,
home: const ChooseAccountPage()));
}
}
/// The Zulip "brand color", a purplish blue.
///
/// This is chosen as the sRGB midpoint of the Zulip logo's gradient.
// As computed by Anders: https://github.com/zulip/zulip-mobile/pull/4467
const kZulipBrandColor = Color.fromRGBO(0x64, 0x92, 0xfe, 1);
class ChooseAccountPage extends StatelessWidget {
const ChooseAccountPage({super.key});
Widget _buildAccountItem(
BuildContext context, {
required int accountId,
required Widget title,
Widget? subtitle,
}) {
return Card(
clipBehavior: Clip.hardEdge,
child: ListTile(
title: title,
subtitle: subtitle,
onTap: () => Navigator.push(context,
HomePage.buildRoute(accountId: accountId))));
}
@override
Widget build(BuildContext context) {
assert(!PerAccountStoreWidget.debugExistsOf(context));
final globalStore = GlobalStoreWidget.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Choose account'),
actions: const [ChooseAccountPageOverflowButton()]),
body: SafeArea(
minimum: const EdgeInsets.all(8),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
for (final (:accountId, :account) in globalStore.accountEntries)
_buildAccountItem(context,
accountId: accountId,
title: Text(account.realmUrl.toString()),
subtitle: Text(account.email)),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () => Navigator.push(context,
AddAccountPage.buildRoute()),
child: const Text('Add an account')),
]))),
));
}
}
enum ChooseAccountPageOverflowMenuItem { aboutZulip }
class ChooseAccountPageOverflowButton extends StatelessWidget {
const ChooseAccountPageOverflowButton({super.key});
@override
Widget build(BuildContext context) {
return PopupMenuButton<ChooseAccountPageOverflowMenuItem>(
itemBuilder: (BuildContext context) => const [
PopupMenuItem(
value: ChooseAccountPageOverflowMenuItem.aboutZulip,
child: Text('About Zulip')),
],
onSelected: (item) {
switch (item) {
case ChooseAccountPageOverflowMenuItem.aboutZulip:
Navigator.push(context, AboutZulipPage.buildRoute(context));
}
});
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
static Route<void> buildRoute({required int accountId}) {
return MaterialPageRoute(builder: (context) =>
PerAccountStoreWidget(accountId: accountId,
child: const HomePage()));
}
@override
Widget build(BuildContext context) {
final store = PerAccountStoreWidget.of(context);
InlineSpan bold(String text) => TextSpan(
text: text, style: const TextStyle(fontWeight: FontWeight.bold));
int? testStreamId;
if (store.connection.realmUrl.origin == 'https://chat.zulip.org') {
testStreamId = 7; // i.e. `#test here`; TODO cut this scaffolding hack
}
return Scaffold(
appBar: AppBar(title: const Text("Home")),
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
DefaultTextStyle.merge(
style: const TextStyle(fontSize: 18),
child: Column(children: [
const Text('🚧 Under construction 🚧'),
const SizedBox(height: 12),
Text.rich(TextSpan(
text: 'Connected to: ',
children: [bold(store.account.realmUrl.toString())])),
Text.rich(TextSpan(
text: 'Zulip server version: ',
children: [bold(store.zulipVersion)])),
Text.rich(TextSpan(text: 'Subscribed to ', children: [
bold(store.subscriptions.length.toString()),
const TextSpan(text: ' streams'),
])),
])),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => Navigator.push(context,
MessageListPage.buildRoute(context: context,
narrow: const AllMessagesNarrow())),
child: const Text("All messages")),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => Navigator.push(context,
RecentDmConversationsPage.buildRoute(context: context)),
child: const Text("Direct messages")),
if (testStreamId != null) ...[
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => Navigator.push(context,
MessageListPage.buildRoute(context: context,
narrow: StreamNarrow(testStreamId!))),
child: const Text("#test here")), // scaffolding hack, see above
],
])));
}
}