mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 14:48:41 +00:00
improve settings view
This commit is contained in:
parent
d13de25f96
commit
6a342380b3
8 changed files with 105 additions and 127 deletions
|
|
@ -8,16 +8,15 @@ import 'package:logging/logging.dart';
|
|||
import 'package:twonly/src/providers/download_change_provider.dart';
|
||||
import 'package:twonly/src/providers/messages_change_provider.dart';
|
||||
import 'package:twonly/src/providers/contacts_change_provider.dart';
|
||||
import 'package:twonly/src/providers/settings_change_provider.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'src/app.dart';
|
||||
import 'src/settings/settings_controller.dart';
|
||||
import 'src/settings/settings_service.dart';
|
||||
|
||||
late DbProvider dbProvider;
|
||||
late ApiProvider apiProvider;
|
||||
|
||||
void main() async {
|
||||
final settingsController = SettingsController(SettingsService());
|
||||
final settingsController = SettingsChangeProvider();
|
||||
|
||||
// Load the user's preferred theme while the splash screen is displayed.
|
||||
// This prevents a sudden theme change when the app is first displayed.
|
||||
|
|
@ -62,8 +61,9 @@ void main() async {
|
|||
ChangeNotifierProvider(create: (_) => MessagesChangeProvider()),
|
||||
ChangeNotifierProvider(create: (_) => DownloadChangeProvider()),
|
||||
ChangeNotifierProvider(create: (_) => ContactChangeProvider()),
|
||||
ChangeNotifierProvider(create: (_) => settingsController),
|
||||
],
|
||||
child: MyApp(settingsController: settingsController),
|
||||
child: MyApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:twonly/main.dart';
|
|||
import 'package:twonly/src/providers/contacts_change_provider.dart';
|
||||
import 'package:twonly/src/providers/download_change_provider.dart';
|
||||
import 'package:twonly/src/providers/messages_change_provider.dart';
|
||||
import 'package:twonly/src/providers/settings_change_provider.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/onboarding_view.dart';
|
||||
import 'package:twonly/src/views/home_view.dart';
|
||||
|
|
@ -11,7 +12,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'dart:async';
|
||||
import 'settings/settings_controller.dart';
|
||||
|
||||
// these global function can be called from anywhere to update
|
||||
// the ui when something changed. The callbacks will be set by
|
||||
|
|
@ -27,9 +27,7 @@ Function(List<int>, bool) globalCallBackOnDownloadChange = (a, b) {};
|
|||
|
||||
/// The Widget that configures your application.
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({super.key, required this.settingsController});
|
||||
|
||||
final SettingsController settingsController;
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => _MyAppState();
|
||||
|
|
@ -114,7 +112,7 @@ class _MyAppState extends State<MyApp> {
|
|||
// The ListenableBuilder Widget listens to the SettingsController for changes.
|
||||
// Whenever the user updates their settings, the MaterialApp is rebuilt.
|
||||
return ListenableBuilder(
|
||||
listenable: widget.settingsController,
|
||||
listenable: context.watch<SettingsChangeProvider>(),
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return MaterialApp(
|
||||
restorationScopeId: 'app',
|
||||
|
|
@ -141,7 +139,7 @@ class _MyAppState extends State<MyApp> {
|
|||
inputDecorationTheme:
|
||||
const InputDecorationTheme(border: OutlineInputBorder()),
|
||||
),
|
||||
themeMode: widget.settingsController.themeMode,
|
||||
themeMode: context.watch<SettingsChangeProvider>().themeMode,
|
||||
home: Stack(
|
||||
children: [
|
||||
FutureBuilder<bool>(
|
||||
|
|
@ -149,9 +147,7 @@ class _MyAppState extends State<MyApp> {
|
|||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return snapshot.data!
|
||||
? HomeView(
|
||||
settingsController: widget.settingsController,
|
||||
)
|
||||
? HomeView()
|
||||
: _showOnboarding
|
||||
? OnboardingView(
|
||||
callbackOnSuccess: () {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,10 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/services/settings_service.dart';
|
||||
|
||||
import 'settings_service.dart';
|
||||
|
||||
/// A class that many Widgets can interact with to read user settings, update
|
||||
/// user settings, or listen to user settings changes.
|
||||
///
|
||||
/// Controllers glue Data Services to Flutter Widgets. The SettingsController
|
||||
/// uses the SettingsService to store and retrieve user settings.
|
||||
class SettingsController with ChangeNotifier {
|
||||
SettingsController(this._settingsService);
|
||||
|
||||
class SettingsChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
||||
// Make SettingsService a private variable so it is not used directly.
|
||||
final SettingsService _settingsService;
|
||||
final SettingsService _settingsService = SettingsService();
|
||||
|
||||
// Make ThemeMode a private variable so it is not updated directly without
|
||||
// also persisting the changes with the SettingsService.
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'settings_controller.dart';
|
||||
|
||||
/// Displays the various settings that can be customized by the user.
|
||||
///
|
||||
/// When a user changes a setting, the SettingsController is updated and
|
||||
/// Widgets that listen to the SettingsController are rebuilt.
|
||||
class SettingsView extends StatelessWidget {
|
||||
const SettingsView({required this.controller});
|
||||
|
||||
final SettingsController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Settings'),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
// Glue the SettingsController to the theme selection DropdownButton.
|
||||
//
|
||||
// When a user selects a theme from the dropdown list, the
|
||||
// SettingsController is updated, which rebuilds the MaterialApp.
|
||||
child: DropdownButton<ThemeMode>(
|
||||
// Read the selected themeMode from the controller
|
||||
value: controller.themeMode,
|
||||
// Call the updateThemeMode method any time the user selects a theme.
|
||||
onChanged: controller.updateThemeMode,
|
||||
items: const [
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.system,
|
||||
child: Text('System Theme'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.light,
|
||||
child: Text('Light Theme'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.dark,
|
||||
child: Text('Dark Theme'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
showLicensePage(context: context);
|
||||
},
|
||||
child: Text('Show Licenses'),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:twonly/src/components/flame.dart';
|
||||
import 'package:twonly/src/components/initialsavatar.dart';
|
||||
|
|
@ -14,6 +15,7 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/views/chat_item_details_view.dart';
|
||||
import 'package:twonly/src/views/home_view.dart';
|
||||
import 'package:twonly/src/views/media_viewer_view.dart';
|
||||
import 'package:twonly/src/views/profile_view.dart';
|
||||
import 'package:twonly/src/views/search_username_view.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -70,12 +72,23 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.chatsTitle),
|
||||
title: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProfileView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text("twonly"),
|
||||
),
|
||||
// title:
|
||||
actions: [
|
||||
NotificationBadge(
|
||||
count: context.watch<ContactChangeProvider>().newContactRequests,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.person_add),
|
||||
icon: FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
|
@ -85,6 +98,17 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProfileView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: FaIcon(FontAwesomeIcons.gear, size: 19),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,15 +2,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||
import 'package:pie_menu/pie_menu.dart';
|
||||
import 'camera_preview_view.dart';
|
||||
import 'chat_list_view.dart';
|
||||
import 'profile_view.dart';
|
||||
import '../settings/settings_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Function(int) globalUpdateOfHomeViewPageIndex = (a) {};
|
||||
|
||||
class HomeView extends StatefulWidget {
|
||||
const HomeView({super.key, required this.settingsController});
|
||||
final SettingsController settingsController;
|
||||
const HomeView({super.key});
|
||||
|
||||
@override
|
||||
State<HomeView> createState() => HomeViewState();
|
||||
|
|
@ -71,7 +68,7 @@ class HomeViewState extends State<HomeView> {
|
|||
children: [
|
||||
ChatListView(),
|
||||
CameraPreviewViewPermission(),
|
||||
ProfileView(settingsController: widget.settingsController)
|
||||
// ProfileView(settingsController: widget.settingsController)
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
|
|
@ -86,8 +83,8 @@ class HomeViewState extends State<HomeView> {
|
|||
icon: FaIcon(FontAwesomeIcons.camera),
|
||||
label: "",
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: FaIcon(FontAwesomeIcons.userShield), label: ""),
|
||||
// BottomNavigationBarItem(
|
||||
// icon: FaIcon(FontAwesomeIcons.userShield), label: ""),
|
||||
],
|
||||
onTap: (int index) {
|
||||
activePageIdx = index;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:twonly/src/model/json/user_data.dart';
|
||||
import 'package:restart_app/restart_app.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/settings/settings_controller.dart';
|
||||
import 'package:twonly/src/settings/settings_view.dart';
|
||||
import 'package:twonly/src/providers/settings_change_provider.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
||||
class ProfileView extends StatefulWidget {
|
||||
const ProfileView({super.key, required this.settingsController});
|
||||
const ProfileView({super.key});
|
||||
|
||||
final SettingsController settingsController;
|
||||
// final SettingsController settingsController;
|
||||
|
||||
@override
|
||||
State<ProfileView> createState() => _ProfileViewState();
|
||||
|
|
@ -20,42 +20,68 @@ class _ProfileViewState extends State<ProfileView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
appBar: AppBar(
|
||||
title: FutureBuilder(
|
||||
future: _userData,
|
||||
builder: (context, snap) {
|
||||
if (snap.hasData) {
|
||||
return Text("Hello ${snap.data!.username}!");
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings),
|
||||
future: _userData,
|
||||
builder: (context, snap) {
|
||||
if (snap.hasData) {
|
||||
return Text("Settings");
|
||||
// return Text("Hello ${snap.data!.username}!");
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
// Glue the SettingsController to the theme selection DropdownButton.
|
||||
//
|
||||
// When a user selects a theme from the dropdown list, the
|
||||
// SettingsController is updated, which rebuilds the MaterialApp.
|
||||
child: DropdownButton<ThemeMode>(
|
||||
// Read the selected themeMode from the controller
|
||||
value: context.watch<SettingsChangeProvider>().themeMode,
|
||||
// Call the updateThemeMode method any time the user selects a theme.
|
||||
onChanged: (theme) {
|
||||
context.read<SettingsChangeProvider>().updateThemeMode(theme);
|
||||
},
|
||||
items: const [
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.system,
|
||||
child: Text('System Theme'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.light,
|
||||
child: Text('Light Theme'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: ThemeMode.dark,
|
||||
child: Text('Dark Theme'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// Navigate to the settings page. If the user leaves and returns
|
||||
// to the app after it has been killed while running in the
|
||||
// background, the navigation stack is restored.
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
SettingsView(controller: widget.settingsController)),
|
||||
showLicensePage(context: context);
|
||||
},
|
||||
child: Text('Show Licenses'),
|
||||
),
|
||||
FilledButton.icon(
|
||||
onPressed: () async {
|
||||
await deleteLocalUserData();
|
||||
Restart.restartApp(
|
||||
notificationTitle: 'Successfully logged out',
|
||||
notificationBody: 'Click here to open the app again',
|
||||
);
|
||||
},
|
||||
label: Text("Logout"),
|
||||
icon: Icon(Icons.no_accounts),
|
||||
),
|
||||
]),
|
||||
body: FilledButton.icon(
|
||||
onPressed: () async {
|
||||
await deleteLocalUserData();
|
||||
Restart.restartApp(
|
||||
notificationTitle: 'Successfully logged out',
|
||||
notificationBody: 'Click here to open the app again',
|
||||
);
|
||||
},
|
||||
label: Text("Logout"),
|
||||
icon: Icon(Icons.no_accounts)),
|
||||
);
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue