important bug fixes

url-works
Christopher Schmitt 2024-01-08 19:34:48 +01:00
parent dbba93411a
commit 1add5bb6fe
18 changed files with 690 additions and 491 deletions

View File

@ -6,7 +6,9 @@ class CirclePainter extends CustomPainter {
final double value;
final Color color; // New field for color
CirclePainter(this.value, this.color);
CirclePainter(this.value, this.color) {
print("CirclePainter " + value.toString());
}
@override
void paint(Canvas canvas, Size size) {
@ -15,7 +17,7 @@ class CirclePainter extends CustomPainter {
..style = PaintingStyle.fill;
double radius = Math.pow(((value + 5) * 500 / 100) / 1.5, 1.14).toDouble();
canvas.drawCircle(Offset(size.width / 6, size.height / 4), radius, paint);
canvas.drawCircle(Offset(55, size.height / 4), radius, paint);
}
@override

View File

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
class AppStyle {
// Colors
static const Color backgroundColor = Color(0xFFEEEEEE);
// Text Sizes
static const double textSmaller = 16.0;
static const double headline = 22.0;
static const double text = 16.0;
// Add other styles as needed
}

View File

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:ui';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../definitions/ColorPairs.dart';
@ -15,8 +16,7 @@ class PreferencesService {
// Helper method to save a ColorPair preference
Future<void> saveColorPair(ColorPair colorPair) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString(
_keyColor1, colorPair.backgroundColor.value.toString());
await prefs.setString(_keyColor1, colorPair.backgroundColor.value.toString());
await prefs.setString(_keyColor2, colorPair.textColor.value.toString());
}
@ -79,18 +79,14 @@ class PreferencesService {
// Save a diary entry
Future<void> saveDiaryEntry(DiaryEntry entry) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final Map<String, dynamic> diaryEntriesMap =
json.decode(prefs.getString(_keyDiaryEntries) ?? '{}');
final Map<String, dynamic> diaryEntriesMap = json.decode(prefs.getString(_keyDiaryEntries) ?? '{}');
// Use the date as the ID for the diary entry
final String dateKey = entry.date.toIso8601String().split('T')[0];
// If the entry is new or the date is older than two days, add or update the text
if (!diaryEntriesMap.containsKey(dateKey) ||
DateTime.now().difference(entry.date).inDays > 2) {
final List<String> texts = diaryEntriesMap[dateKey] != null
? List<String>.from(diaryEntriesMap[dateKey]['texts'])
: [];
if (!diaryEntriesMap.containsKey(dateKey) || DateTime.now().difference(entry.date).inDays > 2) {
final List<String> texts = diaryEntriesMap[dateKey] != null ? List<String>.from(diaryEntriesMap[dateKey]['texts']) : [];
texts.addAll(entry.texts);
diaryEntriesMap[dateKey] = {
'percentValue': entry.percentValue,
@ -123,12 +119,36 @@ class PreferencesService {
}).toList();
}
// Method to calculate the streak of daily diary entries
Future<int> calculateStreak() async {
final allEntries = await loadDiaryEntries();
// Sort the entries by date in descending order
allEntries.sort((a, b) => b.date.compareTo(a.date));
int streakCount = 0;
DateTime currentDate = DateTime.now();
// Use a set to store the dates for faster lookup
Set<String> entryDates = allEntries.map((entry) => DateFormat('yyyy-MM-dd').format(entry.date)).toSet();
// Check for today's entry first
if (!entryDates.contains(DateFormat('yyyy-MM-dd').format(currentDate))) {
return 0; // If today's entry is missing, streak is broken
}
while (entryDates.contains(DateFormat('yyyy-MM-dd').format(currentDate))) {
streakCount++;
currentDate = currentDate.subtract(Duration(days: 1)); // Move to the previous day
}
return streakCount;
}
// Set PIN method
Future<void> setPin(int pin) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt(_keyPin, pin);
await prefs.setBool(
_keyPinEnabled, true); // Automatically enable PIN on setting
await prefs.setBool(_keyPinEnabled, true); // Automatically enable PIN on setting
}
// Check PIN method

View File

@ -5,17 +5,16 @@ class QuestionGenerator {
"Welche Begebenheit hat heute dein Herz am meisten erfreut?",
"Was war das Highlight deines Tages, das dir ein Lächeln geschenkt hat?",
"Welche besondere Erfahrung heute hat dir neue Energie und Freude gebracht?",
"how fullfilled do you feel today?",
"how fullfilled do you feel today?",
"how fullfilled do you feel today?",
"how fullfilled do you feel today?",
"how fullfilled do you feel today?",
"how fulfilled do you feel today?",
"how fulfilled do you feel today?",
"how fulfilled do you feel today?",
"how fulfilled do you feel today?",
"how fulfilled do you feel today?",
];
String getQuestionByDate(DateTime date) {
int hash = _generateHashFromDate(date);
int questionIndex =
hash % _questions.length; // Using modulo to select the question
int questionIndex = hash % _questions.length; // Using modulo to select the question
return _questions[questionIndex];
}

View File

@ -70,10 +70,9 @@ class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> {
@override
Widget buildNavigationBar(Color backgroundColor) {
Future<ColorPair> globalColors = PreferencesService().loadColorPair();
return Container(
width: 175,
margin: EdgeInsets.only(left: 130, right: 130, bottom: 30),
margin: EdgeInsets.only(bottom: 30),
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,

View File

@ -6,6 +6,7 @@ class MoodTextAreaWidget extends StatefulWidget {
final bool hasPrefix;
final bool autoFocus;
final bool forceBlinkingCursor;
final TextEditingController? controller;
MoodTextAreaWidget({
Key? key,
@ -14,6 +15,7 @@ class MoodTextAreaWidget extends StatefulWidget {
this.hasPrefix = false,
this.autoFocus = false,
this.forceBlinkingCursor = false,
this.controller,
}) : super(key: key);
@override
@ -28,9 +30,8 @@ class _MoodTextAreaWidgetState extends State<MoodTextAreaWidget> {
@override
void initState() {
super.initState();
String initialText =
widget.hasPrefix ? 'why? ' + widget.initialText : widget.initialText;
_controller = TextEditingController(text: initialText);
//String initialText = widget.hasPrefix ? 'why? ' + widget.initialText : widget.initialText;
_controller = widget.controller ?? TextEditingController(text: widget.hasPrefix ? 'why? ${widget.initialText}' : widget.initialText);
_isEditingEnabled = !widget.isDisabled;
_focusNode.addListener(() {
@ -69,21 +70,22 @@ class _MoodTextAreaWidgetState extends State<MoodTextAreaWidget> {
@override
Widget build(BuildContext context) {
print("initialtext######${widget.initialText}");
if (!_isEditingEnabled) _controller.text = widget.initialText;
return TextField(
controller: _controller,
focusNode: _focusNode,
keyboardType: TextInputType.multiline,
maxLines: null,
enabled: _isEditingEnabled,
cursorColor:
widget.forceBlinkingCursor ? Colors.black : Colors.transparent,
style: TextStyle(color: Colors.black, fontSize: 18),
decoration: InputDecoration(
cursorColor: widget.forceBlinkingCursor ? Colors.black : Colors.transparent,
style: const TextStyle(color: Colors.black, fontSize: 18),
decoration: const InputDecoration(
border: InputBorder.none,
),
onChanged: (value) {
if (widget.hasPrefix && !value.startsWith('why? ')) {
_controller.text = 'why? ' + value;
if (widget.hasPrefix && !value.startsWith('warum? ')) {
_controller.text = _isEditingEnabled ? 'warum? $value' : value;
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length),
);
@ -94,7 +96,9 @@ class _MoodTextAreaWidgetState extends State<MoodTextAreaWidget> {
@override
void dispose() {
_controller.dispose();
if (widget.controller == null) {
_controller.dispose();
}
_focusNode.dispose();
super.dispose();
}

View File

@ -28,17 +28,36 @@ class QuestionSliderWidget extends StatefulWidget {
class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
bool _showDragText = true;
SliderChangeData _sliderData = SliderChangeData(0, 0);
SliderChangeData? _sliderData;
QuestionGenerator generator = QuestionGenerator();
final double changedInitValue = 0.0;
bool initValSet = false;
@override
void initState() {
super.initState();
_sliderData.value = widget.initialSliderValue;
//_sliderData?.value = widget.initialSliderValue;
_sliderData = SliderChangeData(widget.initialSliderValue, 0);
print("innit");
if (!widget.isSliderEnabled) {
_showDragText = false;
}
}
@override
Widget build(BuildContext context) {
if (!widget.isSliderEnabled) {
_sliderData = SliderChangeData(widget.initialSliderValue, 0);
} else {
if (!initValSet && changedInitValue != widget.initialSliderValue) {
initValSet = true;
print("here");
changedInitValue != widget.initialSliderValue;
_sliderData?.value = widget.initialSliderValue;
}
}
print(_sliderData?.value);
return Padding(
padding: const EdgeInsets.fromLTRB(0, 150, 20, 0),
child: Column(
@ -57,7 +76,7 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
),
SizedBox(height: 10),
Text(
generator.getQuestionByDate(widget.date),
widget.questionText == "" ? generator.getQuestionByDate(widget.date) : widget.questionText,
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
],
@ -73,19 +92,17 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
disabledThumbColor: Colors.transparent,
activeTrackColor: widget.sliderColor,
trackShape: RectangularSliderTrackShape(),
inactiveTickMarkColor: Colors.red,
inactiveTickMarkColor: Colors.transparent,
inactiveTrackColor: Colors.transparent,
valueIndicatorColor: Colors.purple,
valueIndicatorColor: Colors.transparent,
overlayColor: Colors.transparent,
activeTickMarkColor: Colors.red,
activeTickMarkColor: Colors.transparent,
showValueIndicator: ShowValueIndicator.always,
disabledInactiveTrackColor: Colors.transparent,
trackHeight: 2,
thumbColor: Colors.transparent,
thumbShape: RoundSliderThumbShape(
enabledThumbRadius: 10.0,
elevation: 0,
disabledThumbRadius: 0),
rangeThumbShape: RoundRangeSliderThumbShape(
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 10.0, elevation: 0, disabledThumbRadius: 0),
rangeThumbShape: const RoundRangeSliderThumbShape(
disabledThumbRadius: 0,
enabledThumbRadius: 0,
elevation: 0,
@ -94,35 +111,32 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
child: Slider(
min: 0.0,
max: 100.0,
value: _sliderData.value,
value: _sliderData!.value,
onChanged: widget.isSliderEnabled
? (value) {
setState(() {
_sliderData.position =
_calculateSliderPosition(context, value);
_sliderData.value = value;
_sliderData?.position = _calculateSliderPosition(context, value);
_sliderData?.value = value;
_showDragText = false;
});
widget.onSliderChanged(SliderChangeData(
_sliderData.value, _sliderData.position));
widget.onSliderChanged(SliderChangeData(_sliderData!.value, _sliderData!.position));
}
: null,
),
),
),
Positioned(
left: _calculateSliderPosition(context, _sliderData.value),
left: _calculateSliderPosition(context, _sliderData!.value) + 10,
top: 12,
child: IgnorePointer(
child: _showDragText
child: (_showDragText && _sliderData!.value == 0)
? Text(
"Drag Me -->",
style: TextStyle(
fontSize: 16, color: widget.sliderColor),
"drag me -->",
style: TextStyle(fontSize: 16, color: widget.sliderColor),
)
: Text(
"${_sliderData.value.toStringAsFixed(0)}%",
style: TextStyle(
fontSize: 20, color: widget.sliderColor),
"${_sliderData!.value.toStringAsFixed(0)}%",
style: TextStyle(fontSize: 20, color: widget.sliderColor),
),
),
),
@ -134,10 +148,9 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
}
double _calculateSliderPosition(BuildContext context, double value) {
double sliderWidth =
MediaQuery.of(context).size.width - 40; // Width minus padding
double sliderWidth = MediaQuery.of(context).size.width - 60; // Width minus padding
double thumbWidth = 48; // Estimate of the thumb width
return (sliderWidth - thumbWidth) * value / 100.0 + thumbWidth / 2;
return ((sliderWidth - thumbWidth) * value / 100.0 + thumbWidth / 2) + 20;
}
}

View File

@ -2,16 +2,20 @@ import 'package:flutter/material.dart';
class WhyWidget extends StatefulWidget {
final TextEditingController controller;
final bool prependWhy;
WhyWidget({Key? key, required this.controller}) : super(key: key);
WhyWidget({
Key? key,
required this.controller,
this.prependWhy = true,
}) : super(key: key);
@override
_WhyWidgetState createState() => _WhyWidgetState();
}
class _WhyWidgetState extends State<WhyWidget> {
final TextEditingController _controller =
TextEditingController(text: "why? ");
//final TextEditingController _controller = TextEditingController(text: "warum? ");
final FocusNode _focusNode = FocusNode();
@override
@ -21,7 +25,7 @@ class _WhyWidgetState extends State<WhyWidget> {
if (!_focusNode.hasFocus) {
setState(() {
// Remove cursor when focus is lost
_controller.text = _controller.text.replaceAll('|', '');
widget.controller.text = widget.controller.text.replaceAll('|', '');
});
}
});
@ -35,21 +39,20 @@ class _WhyWidgetState extends State<WhyWidget> {
@override
Widget build(BuildContext context) {
return TextField(
controller: _controller,
controller: widget.controller,
focusNode: _focusNode,
keyboardType: TextInputType.multiline,
maxLines: null, // Allow for unlimited lines
cursorColor: Colors.transparent, // Hide the default cursor
style: TextStyle(color: Colors.black, fontSize: 18),
decoration: InputDecoration(
style: const TextStyle(color: Colors.black, fontSize: 18),
decoration: const InputDecoration(
border: InputBorder.none, // Make the TextField borderless
),
onChanged: (value) {
// Ensure "why? " is always at the start
if (!value.startsWith('why? ')) {
_controller.text = 'why? ' + value;
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length));
if (widget.prependWhy && !value.startsWith('warum? ')) {
widget.controller.text = 'warum? $value';
widget.controller.selection = TextSelection.fromPosition(TextPosition(offset: widget.controller.text.length));
}
},
);
@ -57,7 +60,7 @@ class _WhyWidgetState extends State<WhyWidget> {
@override
void dispose() {
_controller.dispose();
widget.controller.dispose();
_focusNode.dispose();
super.dispose();
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/BottomNavigationWidget.dart';
@ -26,10 +28,7 @@ class _ColorPageState extends State<ColorPage> {
if (savedColorPair != null) {
// Find the index of the saved color in the colorPairs list
int index = colorPairs.indexWhere(
(pair) =>
pair.backgroundColor.value ==
savedColorPair.backgroundColor.value &&
pair.textColor.value == savedColorPair.textColor.value,
(pair) => pair.backgroundColor.value == savedColorPair.backgroundColor.value && pair.textColor.value == savedColorPair.textColor.value,
);
if (index != -1) {
setState(() {
@ -47,33 +46,39 @@ class _ColorPageState extends State<ColorPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Padding(
padding: const EdgeInsets.fromLTRB(30, 150, 30, 30),
padding: const EdgeInsets.fromLTRB(30, 75, 30, 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 50),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.chevron_left, color: Colors.black), // "<" icon
Text("settings",
style: TextStyle(color: Colors.black, fontSize: 18)),
]),
Align(
alignment: Alignment.topLeft,
child: GestureDetector(
onTap: () {
context.go("/settings");
},
child: const Padding(
padding: EdgeInsets.only(bottom: 50, left: 10, top: 100),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.chevron_left, color: Colors.black),
Text("settings", style: TextStyle(color: Colors.black, fontSize: 18)),
]),
),
),
),
Text("change color", style: TextStyle(fontSize: 24)),
SizedBox(height: 30),
const Text("change color", style: TextStyle(fontSize: 24)),
const SizedBox(height: 30),
Wrap(
spacing: 15, // space between circles horizontally
runSpacing: 15, // space between circles vertically
children: List.generate(
colorPairs.length, (index) => buildColorCircle(index)),
children: List.generate(colorPairs.length, (index) => buildColorCircle(index)),
),
Padding(
padding: const EdgeInsets.only(top: 50.0),
child: Text("Can't find your favorite color?",
style: TextStyle(color: Colors.grey)),
const Padding(
padding: EdgeInsets.only(top: 50.0),
child: Text("Can't find your favorite color?", style: TextStyle(color: Colors.grey)),
),
Text("Wish you a color!", style: TextStyle(color: Colors.grey)),
const Text("Wish you a color!", style: TextStyle(color: Colors.grey)),
],
),
),
@ -84,6 +89,8 @@ class _ColorPageState extends State<ColorPage> {
// Helper function to build a single color circle
Widget buildColorCircle(int index) {
double bubbleWidth = (MediaQuery.of(context).size.width / 3) - 30;
return GestureDetector(
onTap: () async {
setState(() {
@ -92,8 +99,8 @@ class _ColorPageState extends State<ColorPage> {
await PreferencesService().saveColorPair(colorPairs[index]);
},
child: Container(
width: 120,
height: 120,
width: bubbleWidth,
height: bubbleWidth,
padding: EdgeInsets.all(10), // Padding for inner circle effect
decoration: BoxDecoration(
color: colorPairs[index].backgroundColor,
@ -101,16 +108,13 @@ class _ColorPageState extends State<ColorPage> {
),
child: Container(
decoration: BoxDecoration(
border: selectedColorIndex == index
? Border.all(color: Colors.black, width: 1)
: null,
border: selectedColorIndex == index ? Border.all(color: Colors.black, width: 1) : null,
shape: BoxShape.circle,
),
child: Center(
child: Text(
colorPairs[index].name,
style:
TextStyle(color: colorPairs[index].textColor, fontSize: 16),
style: TextStyle(color: colorPairs[index].textColor, fontSize: 16),
),
),
),

View File

@ -1,106 +1,152 @@
/*class EntryPage extends StatelessWidget {
final DateTime date;
EntryPage({Key? key, required this.date}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Date Display'),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => context.go("/statistic"),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Selected Date:",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
DateFormat('yyyy-MM-dd').format(date),
style: TextStyle(fontSize: 20, color: Colors.blue),
),
],
),
),
);
}
}
*/
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import '../../utils/CirclePainter.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/BottomNavigationWidget.dart';
import '../../utils/widgets/MoodTextArea.dart';
import '../../utils/widgets/QuestionSliderWidget.dart';
class EntryPage extends StatelessWidget {
class EntryPage extends StatefulWidget {
final DateTime date;
final PreferencesService prefsService = PreferencesService();
EntryPage({Key? key, required this.date}) : super(key: key);
@override
_EntryPageState createState() => _EntryPageState();
}
class _EntryPageState extends State<EntryPage> {
SliderChangeData sliderData = SliderChangeData(0, 0);
String _moodText = "";
final PreferencesService _prefsService = PreferencesService();
Color backgroundColor = Colors.lightGreenAccent;
Color textColor = Colors.black;
// Add these new class member variables
bool _isEditing = false;
final TextEditingController _textController = TextEditingController();
@override
void initState() {
super.initState();
_loadCurrentDiaryEntry();
_loadColor();
}
void _loadColor() async {
ColorPair colorPair = await _prefsService.loadColorPair();
setState(() {
backgroundColor = colorPair.backgroundColor;
textColor = colorPair.textColor;
});
}
void _loadCurrentDiaryEntry() async {
DiaryEntry? currentEntry = await _prefsService.getDiaryEntryByDate(widget.date);
if (currentEntry != null) {
setState(() {
sliderData.value = currentEntry.percentValue.toDouble();
_moodText = currentEntry.texts.join(" "); // Concatenate all texts
});
} else {
setState(() {
sliderData.value = 0.0;
_moodText = "No text found for this date.";
});
}
// _textController.text = _moodText;
_textController.text = currentEntry != null ? currentEntry!.texts.join(" ") : _moodText;
}
void _toggleEdit() {
setState(() {
_isEditing = !_isEditing;
});
if (!_isEditing) {
_saveEntry();
}
}
void _saveEntry() async {
print("saveEntry....");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Date Display'),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => context.go("/statistic"),
backgroundColor: AppStyle.backgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: [
// Background circle
Padding(
padding: const EdgeInsets.only(top: 250),
child: Positioned.fill(
child: CustomPaint(
painter: CirclePainter(sliderData.value, backgroundColor),
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
context.go("/statistic");
},
child: const Padding(
padding: EdgeInsets.only(left: 25, top: 80),
child: Row(children: [
Icon(size: 25, Icons.chevron_left, color: Colors.black), // "<" icon
SizedBox(
height: 140,
)
]),
),
),
Padding(
padding: const EdgeInsets.only(left: 30),
child: Column(
children: [
Text(
sliderData.value.toString() + "%",
style: TextStyle(color: Colors.black),
),
Text(DateFormat('dd MM yyyy').format(widget.date).toString(),
style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.bold)),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: MoodTextAreaWidget(
initialText: _moodText,
isDisabled: !_isEditing,
hasPrefix: false,
autoFocus: _isEditing,
forceBlinkingCursor: _isEditing,
)),
TextButton(
onPressed: _toggleEdit,
child: Text(
_isEditing ? "Save" : "Edit",
style: TextStyle(fontSize: 18, color: textColor), // Use appropriate styling
),
),
SizedBox(height: 400), // Space for floating bottom navigation bar
],
),
],
),
),
),
body: FutureBuilder<DiaryEntry?>(
future: prefsService.getDiaryEntryByDate(date), // Fetch the diary entry
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// Check if the diary entry exists
if (snapshot.data != null) {
DiaryEntry entry = snapshot.data!;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Selected Date:",
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
DateFormat('yyyy-MM-dd').format(date),
style: TextStyle(fontSize: 20, color: Colors.blue),
),
SizedBox(height: 20),
Text(
"Percent Value: ${entry.percentValue}",
style: TextStyle(fontSize: 18),
),
...entry.texts.map((text) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text),
)),
],
),
);
} else {
// Handle the case when there is no entry for the given date
return Center(
child: Text("No entry found for this date."),
);
}
} else {
// Show loading indicator while waiting for data
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 0),
);
}
}

View File

@ -4,17 +4,23 @@ import 'package:moody/utils/widgets/QuestionSliderWidget.dart';
import '../../utils/CirclePainter.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
class FirstPage extends StatefulWidget {
final bool showSkipText; // Add this line
const FirstPage({Key? key, this.showSkipText = true}) // Modify this line
: super(key: key);
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
SliderChangeData sliderData = SliderChangeData(0, 0);
SliderChangeData sliderData = SliderChangeData(0, 50);
bool _sliderChanged = false;
PreferencesService _prefsService = PreferencesService();
final PreferencesService _prefsService = PreferencesService();
Color backgroundColor = Colors.lightGreenAccent;
Color textColor = Colors.black;
@ -22,9 +28,19 @@ class _FirstPageState extends State<FirstPage> {
@override
void initState() {
super.initState();
_checkExistingEntry();
_loadColor();
}
void _checkExistingEntry() async {
WidgetsBinding.instance?.addPostFrameCallback((_) async {
DiaryEntry? entry = await _prefsService.getDiaryEntryByCurrentDate();
if (entry != null) {
context.go('/home');
}
});
}
void _loadColor() async {
ColorPair colorPair = await PreferencesService().loadColorPair();
setState(() {
@ -44,27 +60,26 @@ class _FirstPageState extends State<FirstPage> {
await _prefsService.saveDiaryEntry(entry);
} catch (e) {
print(
"Error saving entry: $e"); // Consider showing an error dialog or toast instead
print("Error saving entry: $e"); // Consider showing an error dialog or toast instead
}
}
@override
Widget build(BuildContext context) {
return backgroundColor == Colors.lightGreenAccent
? CircularProgressIndicator() // Show loading indicator while color is null
? const CircularProgressIndicator() // Show loading indicator while color is null
: MaterialApp(
home: Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: SafeArea(
child: Stack(
children: [
// Background circle
Positioned.fill(
top: 15,
left: sliderData.position - 70,
top: 63,
left: sliderData.position - 50,
child: CustomPaint(
painter:
CirclePainter(sliderData.value, backgroundColor),
painter: CirclePainter(sliderData.value, backgroundColor),
),
),
// Main content
@ -97,16 +112,15 @@ class _FirstPageState extends State<FirstPage> {
onPressed: () {
context.go('/write', extra: sliderData);
},
child: Padding(
padding: const EdgeInsets.only(left: 25),
child: const Padding(
padding: EdgeInsets.only(left: 25),
child: Text(
"warum?",
style: TextStyle(
color: Colors.black, fontSize: 18),
style: TextStyle(color: Colors.black, fontSize: 18),
),
),
)
: SizedBox.shrink(),
: const SizedBox.shrink(),
],
),
// Skip/Save button
@ -124,12 +138,10 @@ class _FirstPageState extends State<FirstPage> {
}
},
child: _sliderChanged
? Text("save.",
style:
TextStyle(fontSize: 18, color: textColor))
: Text("skip",
style: TextStyle(
fontSize: 18, color: Colors.grey)),
? Text("save.", style: TextStyle(fontSize: 18, color: textColor))
: widget.showSkipText // Use the showSkipText parameter
? const Text("skip", style: TextStyle(fontSize: 18, color: Colors.grey))
: SizedBox.shrink(),
),
),
],

View File

@ -1,22 +1,13 @@
import 'package:flutter/material.dart';
import 'package:moody/utils/definitions/style_guide.dart';
import 'package:moody/views/first_page/first_page.dart';
import '../../utils/CirclePainter.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/BottomNavigationWidget.dart';
import '../../utils/widgets/MoodTextArea.dart';
import '../../utils/widgets/QuestionSliderWidget.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: HomePage(),
);
}
}
import '../../utils/widgets/WhyWidget.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@ -26,90 +17,159 @@ class HomePage extends StatefulWidget {
}
class _HomePageState extends State<HomePage> {
double _sliderValue = 0.0;
String _moodText = "No text given";
SliderChangeData sliderData = SliderChangeData(0, 0);
String _moodText = "";
bool _isTextAreaEditable = false;
final PreferencesService _prefsService = PreferencesService();
Color backgroundColor = Colors.lightGreenAccent;
Color textColor = Colors.black;
bool noData = false;
final TextEditingController _textController = TextEditingController(text: "");
@override
void initState() {
super.initState();
_loadCurrentDiaryEntry();
_loadColor();
}
void _loadColor() async {
ColorPair colorPair = await PreferencesService().loadColorPair();
setState(() {
backgroundColor = colorPair.backgroundColor;
textColor = colorPair.textColor;
});
}
void _loadCurrentDiaryEntry() async {
DiaryEntry? currentEntry = await _prefsService.getDiaryEntryByCurrentDate();
if (currentEntry != null) {
print(currentEntry.texts.join(" "));
setState(() {
_sliderValue = currentEntry.percentValue.toDouble();
_moodText = currentEntry.texts
.join(" "); // Assuming you want to concatenate all texts
sliderData.value = currentEntry.percentValue.toDouble();
print(currentEntry.percentValue);
_moodText = currentEntry.texts.join(" "); // Assuming you want to concatenate all texts
_textController.text = currentEntry.texts.join(" ");
});
setState(() {});
print(sliderData.value);
} else {
setState(() {
_sliderValue = 0.0;
_moodText = "No text given";
noData = true;
});
}
}
void _toggleTextAreaEditability() {
setState(() {
if (_isTextAreaEditable) {
_saveEntry();
}
_isTextAreaEditable = !_isTextAreaEditable;
});
}
void _saveEntry() async {
try {
List<String> texts = _textController.text.isEmpty ? [] : [_textController.text];
print("DerText:${_textController.text}");
DiaryEntry entry = DiaryEntry(
date: DateTime.now(),
percentValue: sliderData.value.toInt(),
texts: texts,
);
await _prefsService.saveDiaryEntry(entry);
} catch (e) {
print("Error saving entry: $e");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
// Background circle
Positioned.fill(
child: CustomPaint(
painter: CirclePainter(_sliderValue, Colors.orange),
return noData
? Scaffold(
body: const FirstPage(showSkipText: false),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 1),
)
: Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: [
// Background circle
Positioned.fill(
top: 25,
left: sliderData.position,
child: CustomPaint(
painter: CirclePainter(sliderData.value, backgroundColor),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
QuestionSliderWidget(
onSliderPositionChanged: (value) {
print("sliderposchanged");
},
sliderColor: textColor,
date: DateTime.now(),
questionText: 'today',
initialSliderValue: sliderData.value.toDouble(),
isSliderEnabled: _isTextAreaEditable,
onSliderChanged: (value) {
setState(() {
sliderData.value = value.value;
});
},
),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*MoodTextAreaWidget(
controller: _textController,
initialText: _moodText,
isDisabled: !_isTextAreaEditable,
hasPrefix: false,
autoFocus: _isTextAreaEditable,
forceBlinkingCursor: _isTextAreaEditable,
),*/
_isTextAreaEditable
? WhyWidget(
controller: _textController,
prependWhy: false,
)
: Column(
children: [
const SizedBox(height: 10),
Text(_textController.text, style: TextStyle(color: textColor, fontSize: 18)),
],
),
const SizedBox(height: 20),
GestureDetector(
onTap: _toggleTextAreaEditability,
child: Text(
_isTextAreaEditable ? "- Save" : "+ Edit",
style: TextStyle(color: textColor, fontSize: 18),
),
),
const SizedBox(height: 600),
],
),
),
],
),
],
),
),
),
SingleChildScrollView(
child: Column(
children: [
QuestionSliderWidget(
onSliderPositionChanged: (value) {
print("sliderposchanged");
},
sliderColor: Colors.purple,
date: DateTime.now(),
questionText: 'this is how it is:',
initialSliderValue: _sliderValue,
isSliderEnabled: true,
onSliderChanged: (value) {
setState(() {
_sliderValue = value.value;
});
},
),
MoodTextAreaWidget(
initialText: _moodText,
isDisabled: !_isTextAreaEditable,
hasPrefix: false,
autoFocus: false,
forceBlinkingCursor: false,
),
ElevatedButton(
onPressed: _toggleTextAreaEditability,
child: Text(_isTextAreaEditable ? "- Save" : "+ Edit"),
),
SizedBox(
height: 100), // Space for floating bottom navigation bar
],
),
),
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 1),
);
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 1),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/BottomNavigationWidget.dart';
import 'widgets/CustomDivider.dart';
@ -23,15 +24,13 @@ class _SettingsPageState extends State<SettingsPage> {
void _loadPinEnabledState() async {
isPinEnabled = await PreferencesService().isPinEnabled();
print("isPinenabled2");
print(isPinEnabled);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffeeeeee),
backgroundColor: AppStyle.backgroundColor,
body: Container(
padding: EdgeInsets.only(bottom: 0),
margin: const EdgeInsets.fromLTRB(30, 30, 30, 0),
@ -46,9 +45,7 @@ class _SettingsPageState extends State<SettingsPage> {
Container(
margin: EdgeInsets.only(bottom: 10),
alignment: Alignment.topLeft,
child: Text('settings',
style:
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
child: Text('settings', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
TextSwitchContainer(
leftText: "change color",
@ -61,8 +58,7 @@ class _SettingsPageState extends State<SettingsPage> {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // or some other placeholder
}
bool pinEnabled =
snapshot.data ?? false; // Default to false if null
bool pinEnabled = snapshot.data ?? false; // Default to false if null
return TextSwitchContainer(
leftText: "pin",
hasSwitch: true,
@ -90,34 +86,30 @@ class _SettingsPageState extends State<SettingsPage> {
child: Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(bottom: 10),
child: Text('community',
style:
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
child: Text('community', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
leftText: "join our discord",
rightText: "fullfilled",
rightText: "fulfilled",
onTap: () => print('Container tapped'),
),
CustomDivider(),
TextSwitchContainer(
leftText: "our instagram",
rightText: "@get.fullfilled",
rightText: "@get.fulfilled",
onTap: () => print('Container tapped'),
),
CustomDivider(),
TextSwitchContainer(
leftText: "share fullfilled with your loved ones",
leftText: "share fulfilled with your loved ones",
onTap: () => print('Container tapped'),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
child: Container(
alignment: Alignment.topLeft,
child: Text('humans behind fullfilled',
style:
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
child: Text('humans behind fulfilled', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
@ -136,8 +128,7 @@ class _SettingsPageState extends State<SettingsPage> {
),
//
ListTile(
title: Text('imprint & privacy policy',
style: TextStyle(color: Colors.grey, fontSize: 15)),
title: Text('imprint & privacy policy', style: TextStyle(color: Colors.grey, fontSize: 15)),
onTap: () => {}, // Implement your logic
),
SizedBox(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart'; // For Haptic Feedback
class StartPage extends StatelessWidget {
@ -30,8 +31,7 @@ class _PinInputScreenState extends State<PinInputScreen> {
}
Future<void> _checkPinStatus() async {
bool pinEnabled = await PreferencesService()
.isPinEnabled(); // Adjust with actual implementation
bool pinEnabled = await PreferencesService().isPinEnabled(); // Adjust with actual implementation
if (!pinEnabled) {
// If no PIN is enabled, navigate to the "/first" route.
// Navigator context will be available after the widget build.
@ -78,7 +78,7 @@ class _PinInputScreenState extends State<PinInputScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade200, // Light gray background
backgroundColor: AppStyle.backgroundColor,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
@ -91,15 +91,11 @@ class _PinInputScreenState extends State<PinInputScreen> {
child: Container(
height: 600,
width: 400,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(50))),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome Back!',
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
Text('Welcome Back!', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
@ -109,9 +105,7 @@ class _PinInputScreenState extends State<PinInputScreen> {
width: 15,
height: 15,
decoration: BoxDecoration(
color: _pin.length > index
? Colors.black
: Colors.transparent,
color: _pin.length > index ? Colors.black : Colors.transparent,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(15),
),
@ -162,8 +156,7 @@ class _PinInputScreenState extends State<PinInputScreen> {
Widget _buildNumberButton(int number) {
return GestureDetector(
onTap: () => _onNumberTap(number),
onTapDown: (_) =>
HapticFeedback.lightImpact(), // Cool haptic feedback on tap
onTapDown: (_) => HapticFeedback.lightImpact(), // Cool haptic feedback on tap
child: Container(
width: 70,
height: 70,

View File

@ -2,54 +2,95 @@ import 'package:flutter/material.dart';
import 'package:moody/views/statistic/widget/calendar_widget.dart';
import 'package:moody/views/statistic/widget/streak_widget.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/BottomNavigationWidget.dart';
class StatisticPage extends StatelessWidget {
class StatisticPage extends StatefulWidget {
@override
_StatisticPageState createState() => _StatisticPageState();
}
class _StatisticPageState extends State<StatisticPage> {
Color backgroundColor = Colors.white; // Default fallback color
Color textColor = Colors.black; // Default fallback color
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_loadColor(); // Load the colors right when the widget is inserted into the tree
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom());
}
void _loadColor() async {
ColorPair colorPair = await PreferencesService().loadColorPair();
if (mounted) {
setState(() {
backgroundColor = colorPair.backgroundColor;
textColor = colorPair.textColor;
});
}
}
void _scrollToBottom() {
if (_scrollController.hasClients) {
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('StatisticsSite')),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 50,
),
StreakWidget(dayCount: 5),
Text(
"browse your memories!",
style: TextStyle(fontSize: 24),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Container(
child: CalendarWidget(
currentDate: DateTime(
DateTime.now().year,
DateTime.now().month - 2,
DateTime.now().day - 3))),
Container(
child: CalendarWidget(
currentDate: DateTime(
DateTime.now().year,
DateTime.now().month - 1,
DateTime.now().day - 1))),
Container(
child: CalendarWidget(currentDate: DateTime.now())),
SizedBox(
height: 50,
)
],
),
home: SafeArea(
child: Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SizedBox(
height: 50,
),
Column(
children: [
FutureBuilder<int>(
future: PreferencesService().calculateStreak(),
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return StreakWidget(
dayCount: snapshot.data!,
color: backgroundColor,
);
} else {
return CircularProgressIndicator(); // or some placeholder
}
},
),
Text(
"browse your memories!",
style: TextStyle(fontSize: 24),
),
],
),
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 50),
Container(child: CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 2, 1))),
Container(child: CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 1, 1))),
Container(child: CalendarWidget(currentDate: DateTime.now())),
SizedBox(
height: 50,
)
],
),
),
]),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton:
CustomBottomNavigationBar(initialSelectedIndex: 0),
),
]),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 0),
),
),
);
}

View File

@ -28,8 +28,7 @@ class _CalendarWidgetState extends State<CalendarWidget> {
void _loadColorPairAndDiaryData() async {
// Load color pair
currentColorPair =
await PreferencesService().loadColorPair() ?? colorPairs[0];
currentColorPair = await PreferencesService().loadColorPair() ?? colorPairs[0];
// Generate date list
//dateList = _generateDateList(widget.currentDate);
@ -52,15 +51,18 @@ class _CalendarWidgetState extends State<CalendarWidget> {
int startDay = dayOfWeek - 1;
if (startDay < 0) startDay = 6;
// Dates from previous month
// Dates from previous month to fill the first row
for (int i = startDay; i > 0; i--) {
list.add(firstOfMonth.subtract(Duration(days: i)));
}
// Dates of current month
// Dates of current month up to the current date
int daysInMonth = DateUtils.getDaysInMonth(date.year, date.month);
DateTime today = DateTime.now();
for (int i = 0; i < daysInMonth; i++) {
list.add(DateTime(date.year, date.month, i + 1));
DateTime current = DateTime(date.year, date.month, i + 1);
if (current.isAfter(today)) break; // Stop adding dates after today
list.add(current);
}
// Adjust list to end with a complete week
@ -74,8 +76,7 @@ class _CalendarWidgetState extends State<CalendarWidget> {
@override
Widget build(BuildContext context) {
double addon = dateList.length > 35 ? 50 : 0;
String monthName =
DateFormat("MMMM yyyy").format(widget.currentDate); // For month header
String monthName = DateFormat("MMMM yyyy").format(widget.currentDate); // For month header
return FutureBuilder<ColorPair>(
future: PreferencesService().loadColorPair(),
@ -91,10 +92,7 @@ class _CalendarWidgetState extends State<CalendarWidget> {
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Text(monthName,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold)), // Month Header
child: Text(monthName, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), // Month Header
),
Expanded(
child: Padding(
@ -106,13 +104,11 @@ class _CalendarWidgetState extends State<CalendarWidget> {
),
itemBuilder: (context, index) {
DateTime date = dateList[index];
bool isCurrentMonth =
date.month == widget.currentDate.month;
bool isCurrentMonth = date.month == widget.currentDate.month;
double opacity = isCurrentMonth ? 1.0 : 0.15;
// Fetching diary entry percentage value
DiaryEntry? entry =
diaryEntries[DateFormat('yyyy-MM-dd').format(date)];
DiaryEntry? entry = diaryEntries[DateFormat('yyyy-MM-dd').format(date)];
if (entry != null) {
print(entry);
print(entry!.date.toString());
@ -120,8 +116,7 @@ class _CalendarWidgetState extends State<CalendarWidget> {
print(entry!.texts);
}
double fillPercentage =
entry != null ? entry.percentValue / 100.0 : 0.0;
double fillPercentage = entry != null ? entry.percentValue / 100.0 : 0.0;
return Center(
child: GestureDetector(
@ -131,13 +126,9 @@ class _CalendarWidgetState extends State<CalendarWidget> {
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
border:
Border.all(color: Colors.black, width: 2),
color: DateTime.now().day == date.day &&
DateTime.now().month == date.month &&
DateTime.now().year == date.year
? Colors
.orange // Setting background color for current day
border: Border.all(color: Colors.black, width: 2),
color: DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year
? Colors.transparent // Setting background color for current day
: isCurrentMonth
? Colors.transparent
: Colors.grey.withOpacity(opacity),
@ -146,12 +137,11 @@ class _CalendarWidgetState extends State<CalendarWidget> {
alignment: Alignment.center,
children: [
CircleWidget(
radius: 25 * fillPercentage,
color: fillPercentage > 0
? colorPair.backgroundColor
: Colors.teal.withOpacity(opacity)),
radius: 25 * fillPercentage, color: fillPercentage > 0 ? colorPair.backgroundColor : Colors.teal.withOpacity(opacity)),
Text(
DateFormat("d").format(date),
DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year
? "today"
: DateFormat("d").format(date),
style: TextStyle(color: Colors.black),
),
],
@ -173,28 +163,20 @@ class _CalendarWidgetState extends State<CalendarWidget> {
Widget _buildDateCell(DateTime date, DiaryEntry? entry) {
bool isCurrentMonth = date.month == widget.currentDate.month;
double opacity = isCurrentMonth ? 1.0 : 0.5;
Color bgColor = entry != null
? currentColorPair.backgroundColor.withOpacity(opacity)
: Colors.transparent;
double fillPercentage = entry != null
? entry.percentValue / 100
: 0; // Assuming percentValue is 0-100
Color bgColor = entry != null ? currentColorPair.backgroundColor.withOpacity(opacity) : Colors.transparent;
double fillPercentage = entry != null ? entry.percentValue / 100 : 0; // Assuming percentValue is 0-100
return GestureDetector(
onTap: () {
context.go('/entry', extra: date);
},
child: Container(
// ... existing decoration adjusted for opacity ...
child: Stack(
alignment: Alignment.center,
children: [
// Inner circle representing diary entry value
CircleWidget(
radius: 25 * fillPercentage, // Adjust radius based on value
color: fillPercentage > 0
? currentColorPair.backgroundColor
: Colors.grey.withOpacity(opacity)),
color: fillPercentage > 0 ? currentColorPair.backgroundColor : Colors.grey.withOpacity(opacity)),
Text(
DateFormat("d").format(date),
style: TextStyle(color: Colors.black),
@ -210,8 +192,7 @@ class CircleWidget extends StatelessWidget {
final double radius;
final Color color;
CircleWidget({Key? key, required this.radius, required this.color})
: super(key: key);
CircleWidget({Key? key, required this.radius, required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -2,53 +2,60 @@ import 'package:flutter/material.dart';
class StreakWidget extends StatelessWidget {
final int dayCount;
final Color color; // Optional color parameter
StreakWidget({Key? key, required this.dayCount}) : super(key: key);
StreakWidget({
Key? key,
required this.dayCount,
this.color = Colors.white, // Default to white if not provided
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Congratulations! Youre currently ",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
Flexible(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"on a ",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.symmetric(vertical: 4),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: Colors.lightGreen,
borderRadius: BorderRadius.circular(20),
return Container(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"Congratulations! Youre currently ",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
Flexible(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"on a ",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
child: Text(
"$dayCount days",
style: TextStyle(
color: Colors.white,
fontSize: 26,
fontWeight: FontWeight.bold,
Container(
margin: const EdgeInsets.symmetric(vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: color, // Use the color provided
borderRadius: BorderRadius.circular(20),
),
child: Text(
"$dayCount days",
style: const TextStyle(
color: Colors.black,
fontSize: 26,
),
),
),
),
Text(
" streak!",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
],
const Text(
" streak!",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
],
),
),
),
],
],
),
);
}
}

View File

@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:moody/views/write_page/widget/why_widget.dart';
import 'package:moody/utils/widgets/WhyWidget.dart';
import '../../utils/CirclePainter.dart';
import '../../utils/definitions/ColorPairs.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/PreferencesService.dart';
import '../../utils/widgets/QuestionSliderWidget.dart';
@ -16,21 +18,32 @@ class WritePage extends StatefulWidget {
class _WritePageState extends State<WritePage> {
SliderChangeData _sliderData = SliderChangeData(0, 0);
bool _sliderChanged = true;
final bool _sliderChanged = true;
final PreferencesService _prefsService = PreferencesService();
TextEditingController _textController = TextEditingController(text: "why? ");
final TextEditingController _textController = TextEditingController(text: "warum? ");
Color backgroundColor = Colors.lightGreenAccent;
Color textColor = Colors.black;
@override
void initState() {
super.initState();
_sliderData = widget.sliderData; // Set the value here
_loadColor();
}
void _loadColor() async {
ColorPair colorPair = await PreferencesService().loadColorPair();
setState(() {
backgroundColor = colorPair.backgroundColor;
textColor = colorPair.textColor;
});
}
void _saveEntry() async {
// Create a DiaryEntry object from the input
try {
List<String> texts =
_textController.text.isEmpty ? [] : [_textController.text];
List<String> texts = _textController.text.isEmpty ? [] : [_textController.text];
print("DerText:${_textController.text}");
DiaryEntry entry = DiaryEntry(
date: DateTime.now(), // or some date picker value
percentValue: _sliderData.value.toInt(),
@ -42,8 +55,7 @@ class _WritePageState extends State<WritePage> {
// Handle successful save here, maybe show a snackbar or navigate away
} catch (e) {
// Handle any errors here, such as invalid percent value or failed save
print(
"Error saving entry: $e"); // Consider showing an error dialog or toast instead
print("Error saving entry: $e"); // Consider showing an error dialog or toast instead
}
}
@ -51,65 +63,64 @@ class _WritePageState extends State<WritePage> {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: [
// Background circle
Positioned.fill(
child: CustomPaint(
painter:
CirclePainter(_sliderData.value, Colors.yellowAccent),
),
child: Stack(
children: [
// Background circle
Positioned.fill(
top: 15,
left: _sliderData.position - 40,
child: CustomPaint(
painter: CirclePainter(_sliderData.value, backgroundColor),
),
// Main content
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
),
// Main content
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
// padding: const EdgeInsets.all(25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
QuestionSliderWidget(
onSliderPositionChanged: (value) {
print("sliderposchanged");
},
sliderColor: Colors.lightBlue,
date: DateTime.now(),
questionText: "How are you today",
initialSliderValue: 0,
isSliderEnabled: true,
onSliderChanged: (value) {
setState(() {
// _sliderValue = value;
});
}),
TextButton(
onPressed: () {
context.go('/write', extra: _sliderData);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(25, 0, 25, 25),
child: WhyWidget(controller: _textController),
),
// padding: const EdgeInsets.all(25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
QuestionSliderWidget(
onSliderPositionChanged: (value) {},
sliderColor: textColor,
date: DateTime.now(),
questionText: "",
initialSliderValue: _sliderData.value,
isSliderEnabled: true,
onSliderChanged: (value) {
_sliderData = value;
setState(() {
// _sliderValue = value;
});
}),
TextButton(
onPressed: () {
context.go('/write', extra: _sliderData);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(25, 0, 25, 25),
child: WhyWidget(controller: _textController),
),
],
),
),
],
),
// Skip/Save button
Positioned(
bottom: 20,
right: 20,
child: TextButton(
onPressed: () {
_saveEntry();
context.go("/home");
},
child: Text(_sliderChanged ? "Save" : "Skip"),
),
),
// Skip/Save button
Positioned(
bottom: 20,
right: 20,
child: TextButton(
onPressed: () {
_saveEntry();
context.go("/home");
},
child: Text(_sliderChanged ? "Save" : "Skip", style: TextStyle(color: textColor, fontSize: 16)),
),
],
),
),
],
),
),
),