improve settings view

This commit is contained in:
otsmr 2025-02-02 23:19:43 +01:00
parent d13de25f96
commit 6a342380b3
8 changed files with 105 additions and 127 deletions

View file

@ -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(),
),
);
}

View file

@ -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: () {

View file

@ -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.

View file

@ -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'),
),
],
));
}
}

View file

@ -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),
)
],
),

View file

@ -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;

View file

@ -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();
@ -25,28 +25,52 @@ class _ProfileViewState extends State<ProfileView> {
future: _userData,
builder: (context, snap) {
if (snap.hasData) {
return Text("Hello ${snap.data!.username}!");
return Text("Settings");
// return Text("Hello ${snap.data!.username}!");
} else {
return Container();
}
}),
actions: [
IconButton(
icon: const Icon(Icons.settings),
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)),
);
},
),
]),
body: FilledButton.icon(
),
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: () {
showLicensePage(context: context);
},
child: Text('Show Licenses'),
),
FilledButton.icon(
onPressed: () async {
await deleteLocalUserData();
Restart.restartApp(
@ -55,7 +79,9 @@ class _ProfileViewState extends State<ProfileView> {
);
},
label: Text("Logout"),
icon: Icon(Icons.no_accounts)),
);
icon: Icon(Icons.no_accounts),
),
],
));
}
}