Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feature addtion to not get reset on restart of app
  • Loading branch information
SURYANSH-RAI committed Oct 29, 2024
1 parent 912819e commit 0c6f02b
Show file tree
Hide file tree
Showing 8 changed files with 602 additions and 37 deletions.
15 changes: 12 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,20 @@ void main() async {
await Babylon.init();

MaidProperties props = await MaidProperties.last;
final settingsService = AppSettingsService();
await settingsService.init();

runApp(
MaidApp(
props: props
)
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AppPreferences()),
ChangeNotifierProvider(create: (_) => CharacterProvider()),
ChangeNotifierProvider(create: (_) => ModelProvider()),
],
child: const MaidApp(
props: props
),
),
);
}

Expand Down
42 changes: 42 additions & 0 deletions lib/providers/app_preferences.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:shared_preferences/shared_preferences.dart';

class AppPreferences extends ChangeNotifier {
final AppSettingsService _settingsService = AppSettingsService();

// Load saved settings on initialization
Future<void> loadSavedSettings() async {
final selectedModel = _settingsService.getSelectedModel();
final modelParameters = _settingsService.getModelParameters();
final selectedCharacter = _settingsService.getSelectedCharacter();
final characterSettings = _settingsService.getCharacterSettings();

if (selectedModel != null) {
// Apply saved model selection
currentModel = selectedModel;
}

if (modelParameters != null) {
// Apply saved model parameters
applyModelParameters(modelParameters);
}

// ... apply other settings as needed ...

notifyListeners();
}

// Save settings when they change
Future<void> updateModelSelection(String modelId) async {
await _settingsService.saveSelectedModel(modelId);
currentModel = modelId;
notifyListeners();
}

Future<void> updateModelParameters(Map<String, dynamic> parameters) async {
await _settingsService.saveModelParameters(parameters);
// Apply parameters
notifyListeners();
}

// ... other methods ...
}
118 changes: 118 additions & 0 deletions lib/services/app_settings_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

class AppSettingsService {
static const String _selectedCharacterKey = 'selected_character';
static const String _selectedModelKey = 'selected_model';
static const String _modelParametersKey = 'model_parameters';
static const String _characterSettingsKey = 'character_settings';

// Singleton instance
static final AppSettingsService _instance = AppSettingsService._internal();
factory AppSettingsService() => _instance;
AppSettingsService._internal();

late SharedPreferences _prefs;

Future<void> init() async {
_prefs = await SharedPreferences.getInstance();
}

// Save methods
Future<void> saveSelectedCharacter(String characterId) async {
await _prefs.setString(_selectedCharacterKey, characterId);
}

Future<void> saveSelectedModel(String modelId) async {
await _prefs.setString(_selectedModelKey, modelId);
}

Future<void> saveModelParameters(Map<String, dynamic> parameters) async {
await _prefs.setString(_modelParametersKey, jsonEncode(parameters));
}

Future<void> saveCharacterSettings(Map<String, dynamic> settings) async {
await _prefs.setString(_characterSettingsKey, jsonEncode(settings));
}

// Load methods
String? getSelectedCharacter() {
return _prefs.getString(_selectedCharacterKey);
}

String? getSelectedModel() {
return _prefs.getString(_selectedModelKey);
}

Map<String, dynamic>? getModelParameters() {
final String? data = _prefs.getString(_modelParametersKey);
if (data == null) return null;
return jsonDecode(data) as Map<String, dynamic>;
}

Map<String, dynamic>? getCharacterSettings() {
final String? data = _prefs.getString(_characterSettingsKey);
if (data == null) return null;
return jsonDecode(data) as Map<String, dynamic>;
}

// Clear methods
Future<void> clearAllSettings() async {
await _prefs.clear();
}

// Model-specific keys
static const String _modelTemperatureKey = 'model_temperature';
static const String _modelMaxTokensKey = 'model_max_tokens';
static const String _modelTopPKey = 'model_top_p';
static const String _modelTopKKey = 'model_top_k';
static const String _modelContextLengthKey = 'model_context_length';

Future<void> saveModelSettings({
required String modelId,
required double temperature,
required int maxTokens,
required double topP,
required int topK,
required int contextLength,
}) async {
await _prefs.setString(_selectedModelKey, modelId);
await _prefs.setDouble(_modelTemperatureKey, temperature);
await _prefs.setInt(_modelMaxTokensKey, maxTokens);
await _prefs.setDouble(_modelTopPKey, topP);
await _prefs.setInt(_modelTopKKey, topK);
await _prefs.setInt(_modelContextLengthKey, contextLength);
}

ModelSettings? getModelSettings() {
final modelId = _prefs.getString(_selectedModelKey);
if (modelId == null) return null;

return ModelSettings(
modelId: modelId,
temperature: _prefs.getDouble(_modelTemperatureKey) ?? 0.7,
maxTokens: _prefs.getInt(_modelMaxTokensKey) ?? 2048,
topP: _prefs.getDouble(_modelTopPKey) ?? 0.9,
topK: _prefs.getInt(_modelTopKKey) ?? 40,
contextLength: _prefs.getInt(_modelContextLengthKey) ?? 4096,
);
}
}

class ModelSettings {
final String modelId;
final double temperature;
final int maxTokens;
final double topP;
final int topK;
final int contextLength;

ModelSettings({
required this.modelId,
required this.temperature,
required this.maxTokens,
required this.topP,
required this.topK,
required this.contextLength,
});
}
117 changes: 85 additions & 32 deletions lib/ui/mobile/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,99 @@ import 'package:maid/ui/mobile/pages/model_settings/ollama_page.dart';
import 'package:maid/ui/mobile/pages/model_settings/open_ai_page.dart';
import 'package:maid/ui/mobile/pages/settings_page.dart';
import 'package:provider/provider.dart';
import 'package:your_app/services/app_settings_service.dart';
import 'package:your_app/models/model_provider.dart';
import 'package:your_app/models/character_provider.dart';

/// The [MobileApp] class represents the main application widget for the mobile platforms.
/// It is a stateless widget that builds the user interface based on the consumed [AppPreferences].
class MobileApp extends StatelessWidget {
/// It is a stateful widget that builds the user interface based on the consumed [AppPreferences].
class MobileApp extends StatefulWidget {
const MobileApp({super.key});

@override
Widget build(BuildContext context) {
return Consumer<AppPreferences>(
builder: appBuilder
);
State<MobileApp> createState() => _MobileAppState();
}

class _MobileAppState extends State<MobileApp> {
final AppSettingsService _settings = AppSettingsService();
bool _isLoading = true;

@override
void initState() {
super.initState();
_loadAllSettings();
}

/// Builds the root widget for the Maid mobile app.
///
/// This function takes in the [context], [appPreferences], and [child] parameters
/// and returns a [MaterialApp] widget that serves as the root of the app.
/// The [MaterialApp] widget is configured with various properties such as the app title,
/// theme, initial route, and route mappings.
/// The [home] property is set to [MobileHomePage], which serves as the default landing page.
Widget appBuilder(BuildContext context, AppPreferences appPreferences, Widget? child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Maid',
theme: Themes.lightTheme(),
darkTheme: Themes.darkTheme(),
themeMode: appPreferences.themeMode,
initialRoute: '/',
routes: {
'/character': (context) => const CharacterCustomizationPage(),
'/characters': (context) => const CharacterBrowserPage(),
'/llamacpp': (context) => const LlamaCppPage(),
'/ollama': (context) => const OllamaPage(),
'/openai': (context) => const OpenAiPage(),
'/mistralai': (context) => const MistralAiPage(),
'/gemini': (context) => const GoogleGeminiPage(),
'/settings': (context) => const SettingsPage(),
'/about': (context) => const AboutPage(),
Future<void> _loadAllSettings() async {
try {
// Load model settings
final modelSettings = _settings.getModelSettings();
final characterId = _settings.getSelectedCharacter();

if (mounted) {
// Apply model settings
if (modelSettings != null) {
final modelProvider = context.read<ModelProvider>();
await modelProvider.setModel(modelSettings.modelId);
modelProvider.updateParameters(
temperature: modelSettings.temperature,
maxTokens: modelSettings.maxTokens,
topP: modelSettings.topP,
topK: modelSettings.topK,
contextLength: modelSettings.contextLength,
);
}

// Apply character settings
if (characterId != null) {
await context.read<CharacterProvider>().selectCharacter(characterId);
}
}
} catch (e) {
debugPrint('Error loading settings: $e');
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
}

@override
Widget build(BuildContext context) {
return Consumer<AppPreferences>(
builder: (context, appPreferences, child) {
if (_isLoading) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
),
);
}

return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Maid',
theme: Themes.lightTheme(),
darkTheme: Themes.darkTheme(),
themeMode: appPreferences.themeMode,
initialRoute: '/',
routes: {
'/character': (context) => const CharacterCustomizationPage(),
'/characters': (context) => const CharacterBrowserPage(),
'/llamacpp': (context) => const LlamaCppPage(),
'/ollama': (context) => const OllamaPage(),
'/openai': (context) => const OpenAiPage(),
'/mistralai': (context) => const MistralAiPage(),
'/gemini': (context) => const GoogleGeminiPage(),
'/settings': (context) => const SettingsPage(),
'/about': (context) => const AboutPage(),
},
home: const MobileHomePage()
);
},
home: const MobileHomePage()
);
}
}
32 changes: 32 additions & 0 deletions lib/ui/shared/screens/home_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:your_app/ui/shared/widgets/settings_drawer.dart';
import 'package:your_app/ui/shared/screens/chat_view.dart';

class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
final modelProvider = context.watch<ModelProvider>();
final characterProvider = context.watch<CharacterProvider>();

return Scaffold(
appBar: AppBar(
title: Text(characterProvider.selectedCharacter?.name ?? 'Maid'),
actions: [
// Model indicator
Padding(
padding: const EdgeInsets.all(8.0),
child: Chip(
label: Text(modelProvider.currentModel?.name ?? 'No Model'),
avatar: const Icon(Icons.memory),
),
),
],
),
body: const ChatView(),
drawer: SettingsDrawer(),
);
}
}
Loading

0 comments on commit 0c6f02b

Please sign in to comment.