Skip to content

Commit

Permalink
Improvements to character loading / saving (#512)
Browse files Browse the repository at this point in the history
* url setState

* fixes to model dropdown

* work on saving

* fixes to character loading / saving

* small improverments
  • Loading branch information
danemadsen authored Apr 24, 2024
1 parent 2abb709 commit 12993a2
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 84 deletions.
1 change: 1 addition & 0 deletions lib/providers/character.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:maid/static/logger.dart';
import 'package:image/image.dart';
import 'package:maid/static/utilities.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class Character extends ChangeNotifier {
File? _profile;
Expand Down
187 changes: 104 additions & 83 deletions lib/ui/mobile/pages/character/character_customization_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,58 @@ class CharacterCustomizationPage extends StatefulWidget {
}

class _CharacterCustomizationPageState extends State<CharacterCustomizationPage> {
bool _regenerate = true;
bool regenerate = true;

late TextEditingController _nameController;
late TextEditingController _descriptionController;
late TextEditingController _personalityController;
late TextEditingController _scenarioController;
late TextEditingController _systemController;
late List<TextEditingController> _greetingControllers;
late List<TextEditingController> _exampleControllers;
late TextEditingController nameController;
late TextEditingController descriptionController;
late TextEditingController personalityController;
late TextEditingController scenarioController;
late TextEditingController systemController;
late List<TextEditingController> greetingControllers;
late List<TextEditingController> exampleControllers;

Future<void> save() async {
final prefs = await SharedPreferences.getInstance();

final characterString = prefs.getString("last_character");
final character = Character.fromMap(json.decode(characterString ?? "{}"));

final String charactersJson = prefs.getString("characters") ?? '[]';
final List charactersList = json.decode(charactersJson);

List<Character> characters;
characters = charactersList.map((characterMap) {
return Character.fromMap(characterMap);
}).toList();

characters.removeWhere((listCharacter) {
return character.hash == listCharacter.hash;
});
characters.insert(0, character);

final String newCharactersJson =
json.encode(characters.map((character) => character.toMap()).toList());

prefs.setString("characters", newCharactersJson);
}

@override
void dispose() {
super.dispose();
_nameController.dispose();
_descriptionController.dispose();
_personalityController.dispose();
_scenarioController.dispose();
_systemController.dispose();
nameController.dispose();
descriptionController.dispose();
personalityController.dispose();
scenarioController.dispose();
systemController.dispose();

for (var controller in _greetingControllers) {
for (var controller in greetingControllers) {
controller.dispose();
}
for (var controller in _exampleControllers) {
for (var controller in exampleControllers) {
controller.dispose();
}

SharedPreferences.getInstance().then((prefs) {
final characterString = prefs.getString("last_character");
final character = Character.fromMap(json.decode(characterString ?? "{}"));

final String charactersJson = prefs.getString("characters") ?? '[]';
final List charactersList = json.decode(charactersJson);

List<Character> characters;
characters = charactersList.map((characterMap) {
return Character.fromMap(characterMap);
}).toList();

characters.removeWhere((listCharacter) {
return character.hash == listCharacter.hash;
});
characters.insert(0, character);

final String newCharactersJson =
json.encode(characters.map((character) => character.toMap()).toList());

prefs.setString("characters", newCharactersJson);
});
save();
}

@override
Expand All @@ -76,25 +80,27 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
appBar: const GenericAppBar(title: "Character Customization"),
body: Consumer<Character>(
builder: (context, character, child) {
if (_regenerate) {
_nameController = TextEditingController(text: character.name);
_descriptionController = TextEditingController(text: character.description);
_personalityController = TextEditingController(text: character.personality);
_scenarioController = TextEditingController(text: character.scenario);
_systemController = TextEditingController(text: character.system);
if (regenerate) {
nameController = TextEditingController(text: character.name);
descriptionController = TextEditingController(text: character.description);
personalityController = TextEditingController(text: character.personality);
scenarioController = TextEditingController(text: character.scenario);
systemController = TextEditingController(text: character.system);

_greetingControllers = List.generate(
greetingControllers = List.generate(
character.greetings.length,
(index) => TextEditingController(text: character.greetings[index]),
);

_exampleControllers = List.generate(
exampleControllers = List.generate(
character.examples.length,
(index) =>
TextEditingController(text: character.examples[index]["content"]),
);

_regenerate = false;
save();

regenerate = false;
}

SharedPreferences.getInstance().then((prefs) {
Expand Down Expand Up @@ -122,21 +128,17 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
children: [
FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CharacterBrowserPage()));
save();
},
child: Text(
"Switch Character",
"Save Changes",
style: Theme.of(context).textTheme.labelLarge,
),
),
const SizedBox(width: 10.0),
FilledButton(
onPressed: () {
_regenerate = true;
regenerate = true;
character.reset();
},
child: Text(
Expand All @@ -151,9 +153,9 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
mainAxisAlignment: MainAxisAlignment.center,
children: [
FilledButton(
onPressed: () async {
_regenerate = true;
await storageOperationDialog(context, character.importImage);
onPressed: () {
regenerate = true;
storageOperationDialog(context, character.importImage);
},
child: Text(
"Load Image",
Expand All @@ -162,8 +164,8 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
),
const SizedBox(width: 10.0),
FilledButton(
onPressed: () async {
await storageOperationDialog(context, character.exportImage);
onPressed: () {
storageOperationDialog(context, character.exportImage);
},
child: Text(
"Save Image",
Expand All @@ -177,8 +179,8 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
mainAxisAlignment: MainAxisAlignment.center,
children: [
FilledButton(
onPressed: () async {
await storageOperationDialog(context, character.exportSTV2);
onPressed: () {
storageOperationDialog(context, character.exportSTV2);
},
child: Text(
"Save STV2 JSON",
Expand All @@ -187,8 +189,8 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
),
const SizedBox(width: 10.0),
FilledButton(
onPressed: () async {
await storageOperationDialog(context, character.exportMCF);
onPressed: () {
storageOperationDialog(context, character.exportMCF);
},
child: Text(
"Save MCF JSON",
Expand All @@ -198,15 +200,34 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
],
),
const SizedBox(height: 15.0),
FilledButton(
onPressed: () async {
_regenerate = true;
await storageOperationDialog(context, character.importJSON);
},
child: Text(
"Load JSON",
style: Theme.of(context).textTheme.labelLarge,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CharacterBrowserPage()));
},
child: Text(
"Switch Character",
style: Theme.of(context).textTheme.labelLarge,
),
),
const SizedBox(width: 10.0),
FilledButton(
onPressed: () {
regenerate = true;
storageOperationDialog(context, character.importJSON);
},
child: Text(
"Load JSON",
style: Theme.of(context).textTheme.labelLarge,
),
),
],
),
const SizedBox(height: 20.0),
Divider(
Expand All @@ -228,7 +249,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
decoration: const InputDecoration(
labelText: "Name",
),
controller: _nameController,
controller: nameController,
onChanged: (value) {
character.name = value;
},
Expand All @@ -240,7 +261,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
TextFieldListTile(
headingText: 'Description',
labelText: 'Description',
controller: _descriptionController,
controller: descriptionController,
onChanged: (value) {
character.description = value;
},
Expand All @@ -249,7 +270,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
TextFieldListTile(
headingText: 'Personality',
labelText: 'Personality',
controller: _personalityController,
controller: personalityController,
onChanged: (value) {
character.personality = value;
},
Expand All @@ -258,7 +279,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
TextFieldListTile(
headingText: 'Scenario',
labelText: 'Scenario',
controller: _scenarioController,
controller: scenarioController,
onChanged: (value) {
character.scenario = value;
},
Expand All @@ -267,7 +288,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
TextFieldListTile(
headingText: 'System Prompt',
labelText: 'System Prompt',
controller: _systemController,
controller: systemController,
onChanged: (value) {
character.system = value;
},
Expand Down Expand Up @@ -312,7 +333,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
TextFieldListTile(
headingText: 'Greeting $i',
labelText: 'Greeting $i',
controller: _greetingControllers[i],
controller: greetingControllers[i],
onChanged: (value) {
character.updateGreeting(i, value);
},
Expand All @@ -337,7 +358,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
children: [
FilledButton(
onPressed: () {
_regenerate = true;
regenerate = true;
character.newExample(true);
},
child: Text(
Expand All @@ -348,7 +369,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
const SizedBox(width: 10.0),
FilledButton(
onPressed: () {
_regenerate = true;
regenerate = true;
character.newExample(false);
},
child: Text(
Expand All @@ -364,7 +385,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
children: [
FilledButton(
onPressed: () {
_regenerate = true;
regenerate = true;
character.newExample(null);
},
child: Text(
Expand All @@ -375,8 +396,8 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
const SizedBox(width: 10.0),
FilledButton(
onPressed: () {
if (_exampleControllers.length >= 2) {
_regenerate = true;
if (exampleControllers.length >= 2) {
regenerate = true;
character.removeLastExample();
}
},
Expand All @@ -393,7 +414,7 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
headingText:
'${character.examples[i]["role"]} content',
labelText: character.examples[i]["role"],
controller: _exampleControllers[i],
controller: exampleControllers[i],
onChanged: (value) {
character.updateExample(i, value);
},
Expand Down
5 changes: 4 additions & 1 deletion lib/ui/mobile/widgets/appbars/home_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ class _HomeAppBarState extends State<HomeAppBar> {
final RenderBox renderBox = iconButtonKey.currentContext!.findRenderObject() as RenderBox;
final Offset offset = renderBox.localToGlobal(Offset.zero);
final Size size = renderBox.size;
final Session session = context.read<Session>();

List<String> options = context.read<Session>().model.options;
session.model.updateOptions();

List<String> options = session.model.options;

List<PopupMenuEntry<dynamic>> modelOptions = options.map((String modelName) => PopupMenuItem(
padding: EdgeInsets.zero,
Expand Down

0 comments on commit 12993a2

Please sign in to comment.