Skip to content

Commit

Permalink
Fixes to CharacterBrowserTile (#515)
Browse files Browse the repository at this point in the history
* fix issue with character card browser

* fix same issue

* work on character browser tiles

* fix browser tile

* fix character browser

* long press character card
  • Loading branch information
danemadsen authored Apr 25, 2024
1 parent 551b601 commit 5165396
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 84 deletions.
32 changes: 19 additions & 13 deletions lib/providers/character.dart
Original file line number Diff line number Diff line change
Expand Up @@ -275,19 +275,25 @@ class Character extends ChangeNotifier {
}

String get hash {
List<String> hashList = [
_name,
_description,
_personality,
_scenario,
_system,
_useGreeting.toString(),
_greetings.join(),
_useExamples.toString(),
_examples.join(),
];

final bytes = utf8.encode(hashList.join());
Uint8List bytes;

if(_profile != null) {
bytes = _profile!.readAsBytesSync();
} else {
List<String> hashList = [
_name,
_description,
_personality,
_scenario,
_system,
_useGreeting.toString(),
_greetings.join(),
_useExamples.toString(),
_examples.join(),
];

bytes = utf8.encode(hashList.join());
}

return sha256.convert(bytes).toString();
}
Expand Down
9 changes: 7 additions & 2 deletions lib/ui/mobile/pages/character/character_browser_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ class _CharacterBrowserPageState extends State<CharacterBrowserPage> {

Future<void> _loadCharacters() async {
final prefs = await SharedPreferences.getInstance();
final String charactersJson = prefs.getString("characters") ?? '[]';

final String? charactersJson = prefs.getString("characters");
if (charactersJson == null) {
return;
}

final List charactersList = json.decode(charactersJson);

setState(() {
characters.clear();
for (var characterMap in charactersList) {
for (final characterMap in charactersList) {
characters.add(Character.fromMap(characterMap));
}
});
Expand Down
26 changes: 17 additions & 9 deletions lib/ui/mobile/pages/character/character_customization_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
final prefs = await SharedPreferences.getInstance();

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

if (characterString == null) {
return;
}

final character = Character.fromMap(json.decode(characterString));

final String charactersJson = prefs.getString("characters") ?? '[]';
final List charactersList = json.decode(charactersJson);
Expand Down Expand Up @@ -80,6 +85,10 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
appBar: const GenericAppBar(title: "Character Customization"),
body: Consumer<Character>(
builder: (context, character, child) {
SharedPreferences.getInstance().then((prefs) {
prefs.setString("last_character", json.encode(character.toMap()));
});

if (regenerate) {
nameController = TextEditingController(text: character.name);
descriptionController = TextEditingController(text: character.description);
Expand All @@ -103,10 +112,6 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
regenerate = false;
}

SharedPreferences.getInstance().then((prefs) {
prefs.setString("last_character", json.encode(character.toMap()));
});

return SessionBusyOverlay(
child: SingleChildScrollView(
child: Column(
Expand Down Expand Up @@ -205,11 +210,14 @@ class _CharacterCustomizationPageState extends State<CharacterCustomizationPage>
children: [
FilledButton(
onPressed: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CharacterBrowserPage()));
context,
MaterialPageRoute(
builder: (context) =>
const CharacterBrowserPage()
)
);
},
child: Text(
"Switch Character",
Expand Down
141 changes: 81 additions & 60 deletions lib/ui/mobile/widgets/tiles/character_browser_tile.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:maid/providers/character.dart';
import 'package:maid/static/logger.dart';
import 'package:maid/ui/mobile/pages/character/character_customization_page.dart';
import 'package:provider/provider.dart';

class CharacterBrowserTile extends StatefulWidget {
Expand All @@ -17,78 +19,97 @@ class CharacterBrowserTile extends StatefulWidget {
}

class _CharacterBrowserTileState extends State<CharacterBrowserTile> {
Timer? longPressTimer;

@override
Widget build(BuildContext context) {
return GestureDetector(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: FutureBuilder<File>(
future: widget.character.profile,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return const Icon(Icons.error);
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
fit: StackFit.expand,
children: [
FutureBuilder<File>(
future: widget.character.profile,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return const Icon(Icons.error);
} else {
return Image.file(
snapshot.data!,
fit: BoxFit.cover,
);
}
} else {
return Stack(
fit: StackFit.expand,
return const CircularProgressIndicator();
}
}
),
Material(
color: Colors.transparent,
child: InkWell(
hoverColor: Colors.black.withOpacity(0.1),
highlightColor: Colors.black.withOpacity(0.2),
splashColor: Colors.black.withOpacity(0.2),
onTapDown: onTapDown,
onTapUp: onTapUp,
onSecondaryTapUp: (details) => showContextMenu(details.globalPosition),
child: Container(
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.center,
colors: [Colors.black, Colors.transparent],
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.file(
snapshot.data!,
fit: BoxFit.cover,
Text(
widget.character.name,
style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [Colors.black.withOpacity(0.8), Colors.transparent],
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.character.name,
style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
widget.character.description,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.white),
),
],
),
),
Text(
widget.character.description,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.white),
),
],
);
}
} else {
return const CircularProgressIndicator();
}
}
)
),
onTap: () {
context.read<Character>().from(widget.character);
},
onSecondaryTapUp: (details) => _onSecondaryTapUp(details, context),
onLongPressStart: (details) => _onLongPressStart(details, context),
),
)
)
)
],
)
);
}

void _onSecondaryTapUp(TapUpDetails details, BuildContext context) =>
_showContextMenu(details.globalPosition, context);
void onTapDown(TapDownDetails details) {
longPressTimer = Timer(const Duration(seconds: 1), () {
showContextMenu(details.globalPosition);
});
}

void _onLongPressStart(LongPressStartDetails details, BuildContext context) =>
_showContextMenu(details.globalPosition, context);
void onTapUp(TapUpDetails details) {
if (longPressTimer?.isActive ?? false) {
longPressTimer?.cancel();
context.read<Character>().from(widget.character);
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CharacterCustomizationPage()
)
);
}
}

void _showContextMenu(Offset position, BuildContext context) {
void showContextMenu(Offset position) {
final RenderBox overlay =
Overlay.of(context).context.findRenderObject() as RenderBox;
final TextEditingController controller =
Expand Down

0 comments on commit 5165396

Please sign in to comment.