added hook for stores
This commit is contained in:
parent
d3eee1e837
commit
c6b03c3aef
|
@ -0,0 +1,8 @@
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../stores/accounts_store.dart';
|
||||||
|
import '../stores/config_store.dart';
|
||||||
|
|
||||||
|
AccountsStore useAccountsStore() => useContext().watch<AccountsStore>();
|
||||||
|
ConfigStore useConfigStore() => useContext().watch<ConfigStore>();
|
|
@ -1,8 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
|
import 'package:lemmur/pages/profile_tab.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'pages/instance.dart';
|
import 'hooks/stores.dart';
|
||||||
import 'stores/accounts_store.dart';
|
import 'stores/accounts_store.dart';
|
||||||
import 'stores/config_store.dart';
|
import 'stores/config_store.dart';
|
||||||
|
|
||||||
|
@ -32,32 +34,34 @@ Future<void> main() async {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Observer(
|
Widget build(BuildContext context) {
|
||||||
builder: (ctx) {
|
final configStore = useConfigStore();
|
||||||
var maybeAmoledColor =
|
|
||||||
ctx.watch<ConfigStore>().amoledDarkMode ? Colors.black : null;
|
|
||||||
|
|
||||||
return MaterialApp(
|
return Observer(
|
||||||
title: 'Flutter Demo',
|
builder: (ctx) {
|
||||||
themeMode: ctx.watch<ConfigStore>().theme,
|
final maybeAmoledColor =
|
||||||
darkTheme: ThemeData.dark().copyWith(
|
configStore.amoledDarkMode ? Colors.black : null;
|
||||||
scaffoldBackgroundColor: maybeAmoledColor,
|
|
||||||
backgroundColor: maybeAmoledColor,
|
return MaterialApp(
|
||||||
canvasColor: maybeAmoledColor,
|
title: 'Flutter Demo',
|
||||||
cardColor: maybeAmoledColor,
|
themeMode: configStore.theme,
|
||||||
splashColor: maybeAmoledColor,
|
darkTheme: ThemeData.dark().copyWith(
|
||||||
),
|
scaffoldBackgroundColor: maybeAmoledColor,
|
||||||
theme: ThemeData(
|
backgroundColor: maybeAmoledColor,
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
canvasColor: maybeAmoledColor,
|
||||||
),
|
cardColor: maybeAmoledColor,
|
||||||
home: InstancePage(
|
splashColor: maybeAmoledColor,
|
||||||
instanceUrl: 'dev.lemmy.ml',
|
),
|
||||||
),
|
theme: ThemeData(
|
||||||
);
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
},
|
),
|
||||||
);
|
home: UserProfileTab(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class MyHomePage extends StatefulWidget {
|
||||||
|
|
|
@ -4,11 +4,10 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:fuzzy/fuzzy.dart';
|
import 'package:fuzzy/fuzzy.dart';
|
||||||
|
import 'package:lemmur/hooks/stores.dart';
|
||||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
import '../hooks/delayed_loading.dart';
|
import '../hooks/delayed_loading.dart';
|
||||||
import '../stores/accounts_store.dart';
|
|
||||||
import '../util/extensions/iterators.dart';
|
import '../util/extensions/iterators.dart';
|
||||||
import '../util/text_color.dart';
|
import '../util/text_color.dart';
|
||||||
|
|
||||||
|
@ -20,9 +19,9 @@ class CommunitiesTab extends HookWidget {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
var filterController = useTextEditingController();
|
var filterController = useTextEditingController();
|
||||||
useValueListenable(filterController);
|
useValueListenable(filterController);
|
||||||
var amountOfDisplayInstances = useMemoized(() {
|
final accountsStore = useAccountsStore();
|
||||||
var accountsStore = context.watch<AccountsStore>();
|
|
||||||
|
|
||||||
|
var amountOfDisplayInstances = useMemoized(() {
|
||||||
return accountsStore.users.keys
|
return accountsStore.users.keys
|
||||||
.where((e) => !accountsStore.isAnonymousFor(e))
|
.where((e) => !accountsStore.isAnonymousFor(e))
|
||||||
.length;
|
.length;
|
||||||
|
@ -31,8 +30,6 @@ class CommunitiesTab extends HookWidget {
|
||||||
|
|
||||||
// TODO: use useMemoFuture
|
// TODO: use useMemoFuture
|
||||||
var instancesFut = useMemoized(() {
|
var instancesFut = useMemoized(() {
|
||||||
var accountsStore = context.watch<AccountsStore>();
|
|
||||||
|
|
||||||
var futures = accountsStore.users.keys
|
var futures = accountsStore.users.keys
|
||||||
.where((e) => !accountsStore.isAnonymousFor(e))
|
.where((e) => !accountsStore.isAnonymousFor(e))
|
||||||
.map(
|
.map(
|
||||||
|
@ -44,8 +41,6 @@ class CommunitiesTab extends HookWidget {
|
||||||
return Future.wait(futures);
|
return Future.wait(futures);
|
||||||
});
|
});
|
||||||
var communitiesFut = useMemoized(() {
|
var communitiesFut = useMemoized(() {
|
||||||
var accountsStore = context.watch<AccountsStore>();
|
|
||||||
|
|
||||||
var futures = accountsStore.users.keys
|
var futures = accountsStore.users.keys
|
||||||
.where((e) => !accountsStore.isAnonymousFor(e))
|
.where((e) => !accountsStore.isAnonymousFor(e))
|
||||||
.map(
|
.map(
|
||||||
|
@ -239,6 +234,7 @@ class _CommunitySubscribeToggle extends HookWidget {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
var subbed = useState(true);
|
var subbed = useState(true);
|
||||||
var delayed = useDelayedLoading(const Duration(milliseconds: 500));
|
var delayed = useDelayedLoading(const Duration(milliseconds: 500));
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
handleTap() async {
|
handleTap() async {
|
||||||
delayed.start();
|
delayed.start();
|
||||||
|
@ -247,10 +243,7 @@ class _CommunitySubscribeToggle extends HookWidget {
|
||||||
await LemmyApi(instanceUrl).v1.followCommunity(
|
await LemmyApi(instanceUrl).v1.followCommunity(
|
||||||
communityId: communityId,
|
communityId: communityId,
|
||||||
follow: !subbed.value,
|
follow: !subbed.value,
|
||||||
auth: context
|
auth: accountsStore.defaultTokenFor(instanceUrl).raw,
|
||||||
.read<AccountsStore>()
|
|
||||||
.defaultTokenFor(instanceUrl)
|
|
||||||
.raw,
|
|
||||||
);
|
);
|
||||||
subbed.value = !subbed.value;
|
subbed.value = !subbed.value;
|
||||||
} on Exception catch (err) {
|
} on Exception catch (err) {
|
||||||
|
|
|
@ -6,12 +6,11 @@ import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:lemmur/hooks/stores.dart';
|
||||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:url_launcher/url_launcher.dart' as ul;
|
import 'package:url_launcher/url_launcher.dart' as ul;
|
||||||
|
|
||||||
import '../hooks/memo_future.dart';
|
import '../hooks/memo_future.dart';
|
||||||
import '../stores/accounts_store.dart';
|
|
||||||
import '../util/api_extensions.dart';
|
import '../util/api_extensions.dart';
|
||||||
import '../util/goto.dart';
|
import '../util/goto.dart';
|
||||||
import '../util/intl.dart';
|
import '../util/intl.dart';
|
||||||
|
@ -49,8 +48,10 @@ class CommunityPage extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
var fullCommunitySnap = useMemoFuture(() {
|
var fullCommunitySnap = useMemoFuture(() {
|
||||||
final token = context.watch<AccountsStore>().defaultTokenFor(instanceUrl);
|
final token = accountsStore.defaultTokenFor(instanceUrl);
|
||||||
|
|
||||||
if (communityId != null) {
|
if (communityId != null) {
|
||||||
return LemmyApi(instanceUrl).v1.getCommunity(
|
return LemmyApi(instanceUrl).v1.getCommunity(
|
||||||
|
@ -535,14 +536,14 @@ class _FollowButton extends HookWidget {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final isSubbed = useState(community.subscribed ?? false);
|
final isSubbed = useState(community.subscribed ?? false);
|
||||||
|
|
||||||
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
|
final token = useAccountsStore().defaultTokenFor(community.instanceUrl);
|
||||||
final token =
|
|
||||||
context.watch<AccountsStore>().defaultTokenFor(community.instanceUrl);
|
|
||||||
|
|
||||||
// TODO: use hook for handling spinner and pending
|
// TODO: use hook for handling spinner and pending
|
||||||
final showSpinner = useState(false);
|
final showSpinner = useState(false);
|
||||||
final isPending = useState(false);
|
final isPending = useState(false);
|
||||||
|
|
||||||
|
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
|
||||||
|
|
||||||
subscribe() async {
|
subscribe() async {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
Scaffold.of(context).showSnackBar(
|
Scaffold.of(context).showSnackBar(
|
||||||
|
|
|
@ -2,9 +2,8 @@ import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:lemmur/hooks/stores.dart';
|
||||||
|
|
||||||
import '../stores/accounts_store.dart';
|
|
||||||
import '../util/api_extensions.dart';
|
import '../util/api_extensions.dart';
|
||||||
import '../util/goto.dart';
|
import '../util/goto.dart';
|
||||||
import '../widgets/bottom_modal.dart';
|
import '../widgets/bottom_modal.dart';
|
||||||
|
@ -17,10 +16,11 @@ class UserProfileTab extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
return Observer(
|
return Observer(
|
||||||
builder: (ctx) {
|
builder: (ctx) {
|
||||||
if (ctx.watch<AccountsStore>().hasNoAccount) {
|
if (accountsStore.hasNoAccount) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -40,7 +40,7 @@ class UserProfileTab extends HookWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = ctx.watch<AccountsStore>().defaultUser;
|
var user = accountsStore.defaultUser;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
extendBodyBehindAppBar: true,
|
extendBodyBehindAppBar: true,
|
||||||
|
@ -71,10 +71,7 @@ class UserProfileTab extends HookWidget {
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
var userTags = <String>[];
|
var userTags = <String>[];
|
||||||
|
|
||||||
ctx
|
accountsStore.users.forEach((instanceUrl, value) {
|
||||||
.read<AccountsStore>()
|
|
||||||
.users
|
|
||||||
.forEach((instanceUrl, value) {
|
|
||||||
value.forEach((username, _) {
|
value.forEach((username, _) {
|
||||||
userTags.add('$username@$instanceUrl');
|
userTags.add('$username@$instanceUrl');
|
||||||
});
|
});
|
||||||
|
@ -82,7 +79,7 @@ class UserProfileTab extends HookWidget {
|
||||||
|
|
||||||
return Observer(
|
return Observer(
|
||||||
builder: (ctx) {
|
builder: (ctx) {
|
||||||
var user = ctx.watch<AccountsStore>().defaultUser;
|
var user = accountsStore.defaultUser;
|
||||||
var instanceUrl = user.instanceUrl;
|
var instanceUrl = user.instanceUrl;
|
||||||
|
|
||||||
return BottomModal(
|
return BottomModal(
|
||||||
|
@ -96,7 +93,7 @@ class UserProfileTab extends HookWidget {
|
||||||
groupValue: '${user.name}@$instanceUrl',
|
groupValue: '${user.name}@$instanceUrl',
|
||||||
onChanged: (selected) {
|
onChanged: (selected) {
|
||||||
var userTag = selected.split('@');
|
var userTag = selected.split('@');
|
||||||
ctx.read<AccountsStore>().setDefaultAccount(
|
accountsStore.setDefaultAccount(
|
||||||
userTag[1], userTag[0]);
|
userTag[1], userTag[0]);
|
||||||
Navigator.of(ctx).pop();
|
Navigator.of(ctx).pop();
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,10 +2,8 @@ import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:lemmur/hooks/stores.dart';
|
||||||
|
|
||||||
import '../stores/accounts_store.dart';
|
|
||||||
import '../stores/config_store.dart';
|
|
||||||
import '../util/goto.dart';
|
import '../util/goto.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
|
@ -49,6 +47,7 @@ class AppearanceConfigPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
final configStore = useConfigStore();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -66,16 +65,16 @@ class AppearanceConfigPage extends StatelessWidget {
|
||||||
RadioListTile<ThemeMode>(
|
RadioListTile<ThemeMode>(
|
||||||
value: theme,
|
value: theme,
|
||||||
title: Text(theme.toString().split('.')[1]),
|
title: Text(theme.toString().split('.')[1]),
|
||||||
groupValue: ctx.watch<ConfigStore>().theme,
|
groupValue: configStore.theme,
|
||||||
onChanged: (selected) {
|
onChanged: (selected) {
|
||||||
ctx.read<ConfigStore>().theme = selected;
|
configStore.theme = selected;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text('AMOLED dark mode'),
|
title: Text('AMOLED dark mode'),
|
||||||
value: ctx.watch<ConfigStore>().amoledDarkMode,
|
value: configStore.amoledDarkMode,
|
||||||
onChanged: (checked) {
|
onChanged: (checked) {
|
||||||
ctx.read<ConfigStore>().amoledDarkMode = checked;
|
configStore.amoledDarkMode = checked;
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -90,6 +89,7 @@ class AccountsConfigPage extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
|
@ -112,7 +112,6 @@ class AccountsConfigPage extends HookWidget {
|
||||||
),
|
),
|
||||||
body: Observer(
|
body: Observer(
|
||||||
builder: (ctx) {
|
builder: (ctx) {
|
||||||
var accountsStore = ctx.watch<AccountsStore>();
|
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
|
@ -168,15 +167,14 @@ class _AccountsConfigAddInstanceDialog extends HookWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var instanceController = useTextEditingController();
|
var instanceController = useTextEditingController();
|
||||||
useValueListenable(instanceController);
|
useValueListenable(instanceController);
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
var loading = useState(false);
|
var loading = useState(false);
|
||||||
|
|
||||||
handleOnAdd() async {
|
handleOnAdd() async {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await context
|
await accountsStore.addInstance(instanceController.text);
|
||||||
.read<AccountsStore>()
|
|
||||||
.addInstance(instanceController.text);
|
|
||||||
scaffoldKey.currentState.hideCurrentSnackBar();
|
scaffoldKey.currentState.hideCurrentSnackBar();
|
||||||
} on Exception catch (err) {
|
} on Exception catch (err) {
|
||||||
scaffoldKey.currentState.showSnackBar(SnackBar(
|
scaffoldKey.currentState.showSnackBar(SnackBar(
|
||||||
|
@ -226,17 +224,18 @@ class _AccountsConfigAddAccountDialog extends HookWidget {
|
||||||
var passwordController = useTextEditingController();
|
var passwordController = useTextEditingController();
|
||||||
useValueListenable(usernameController);
|
useValueListenable(usernameController);
|
||||||
useValueListenable(passwordController);
|
useValueListenable(passwordController);
|
||||||
|
final accountsStore = useAccountsStore();
|
||||||
|
|
||||||
var loading = useState(false);
|
var loading = useState(false);
|
||||||
|
|
||||||
handleOnAdd() async {
|
handleOnAdd() async {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await context.read<AccountsStore>().addAccount(
|
await accountsStore.addAccount(
|
||||||
instanceUrl,
|
instanceUrl,
|
||||||
usernameController.text,
|
usernameController.text,
|
||||||
passwordController.text,
|
passwordController.text,
|
||||||
);
|
);
|
||||||
} on Exception catch (err) {
|
} on Exception catch (err) {
|
||||||
scaffoldKey.currentState.showSnackBar(SnackBar(
|
scaffoldKey.currentState.showSnackBar(SnackBar(
|
||||||
content: Text(err.toString()),
|
content: Text(err.toString()),
|
||||||
|
|
Loading…
Reference in New Issue