design + logic updates
parent
9b5b09045b
commit
79380eb2e0
|
@ -1,11 +1,13 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:moody/utils/SlideDirection.dart';
|
import 'package:moody/utils/SlideDirection.dart';
|
||||||
|
import 'package:moody/views/color_page/color_page.dart';
|
||||||
import 'package:moody/views/entry_view/entry_page.dart';
|
import 'package:moody/views/entry_view/entry_page.dart';
|
||||||
import 'package:moody/views/first_page/first_page.dart';
|
import 'package:moody/views/first_page/first_page.dart';
|
||||||
import 'package:moody/views/home_page/home_page.dart';
|
import 'package:moody/views/home_page/home_page.dart';
|
||||||
import 'package:moody/views/home_page/kalendartryhome_page.dart';
|
import 'package:moody/views/home_page/kalendartryhome_page.dart';
|
||||||
import 'package:moody/views/settings_page/settings_page.dart';
|
import 'package:moody/views/settings_page/settings_page.dart';
|
||||||
|
import 'package:moody/views/start_page/start_page.dart';
|
||||||
import 'package:moody/views/statistic/statistic_page.dart';
|
import 'package:moody/views/statistic/statistic_page.dart';
|
||||||
import 'package:moody/views/write_page/write_page.dart';
|
import 'package:moody/views/write_page/write_page.dart';
|
||||||
|
|
||||||
|
@ -16,7 +18,7 @@ final GoRouter _router = GoRouter(
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
pageBuilder: (context, state) =>
|
pageBuilder: (context, state) =>
|
||||||
_noAnimationTransition(context, state, FirstPage()),
|
_noAnimationTransition(context, state, StartPage()),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/moods',
|
path: '/moods',
|
||||||
|
@ -37,6 +39,16 @@ final GoRouter _router = GoRouter(
|
||||||
pageBuilder: (context, state) =>
|
pageBuilder: (context, state) =>
|
||||||
_noAnimationTransition(context, state, HomePage()),
|
_noAnimationTransition(context, state, HomePage()),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/first',
|
||||||
|
pageBuilder: (context, state) =>
|
||||||
|
_noAnimationTransition(context, state, FirstPage()),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/color',
|
||||||
|
pageBuilder: (context, state) =>
|
||||||
|
_noAnimationTransition(context, state, ColorPage()),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/write',
|
path: '/write',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
|
import 'dart:math' as Math;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class CirclePainter extends CustomPainter {
|
class CirclePainter extends CustomPainter {
|
||||||
final double value;
|
final double value;
|
||||||
|
final Color color; // New field for color
|
||||||
|
|
||||||
CirclePainter(this.value);
|
CirclePainter(this.value, this.color);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
var paint = Paint()
|
var paint = Paint()
|
||||||
..color = Colors.greenAccent.withOpacity(0.5)
|
..color = color.withOpacity(0.5) // Use the passed color
|
||||||
..style = PaintingStyle.fill;
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
double radius = value * 500 / 100;
|
double radius = Math.pow(((value + 5) * 500 / 100) / 1.5, 1.14).toDouble();
|
||||||
print(radius);
|
|
||||||
|
|
||||||
canvas.drawCircle(Offset(size.width / 6, size.height / 4), radius, paint);
|
canvas.drawCircle(Offset(size.width / 6, size.height / 4), radius, paint);
|
||||||
//print(size.width / 6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ColorPair {
|
||||||
|
final Color textColor;
|
||||||
|
final Color backgroundColor;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
ColorPair(
|
||||||
|
{required this.name,
|
||||||
|
required this.textColor,
|
||||||
|
required this.backgroundColor});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ColorPair> colorPairs = [
|
||||||
|
ColorPair(
|
||||||
|
name: "origin",
|
||||||
|
textColor: Color(0xff446F2F),
|
||||||
|
backgroundColor: Color(0xffC9E7BB)),
|
||||||
|
ColorPair(
|
||||||
|
name: "lavender",
|
||||||
|
textColor: Color(0xff765EAB),
|
||||||
|
backgroundColor: Color(0xffD3CAE7)),
|
||||||
|
ColorPair(
|
||||||
|
name: "orange",
|
||||||
|
textColor: Color(0xffC78233),
|
||||||
|
backgroundColor: Color(0xffF0CFA9)),
|
||||||
|
ColorPair(
|
||||||
|
name: "rose",
|
||||||
|
textColor: Color(0xffB15555),
|
||||||
|
backgroundColor: Color(0xffEBD6D6)),
|
||||||
|
ColorPair(
|
||||||
|
name: "mountain",
|
||||||
|
textColor: Color(0xff1D6289),
|
||||||
|
backgroundColor: Color(0xffB4D0E0)),
|
||||||
|
ColorPair(
|
||||||
|
name: "moon",
|
||||||
|
textColor: Color(0xff7A83C7),
|
||||||
|
backgroundColor: Color(0xff393C55)),
|
||||||
|
ColorPair(
|
||||||
|
name: "forest",
|
||||||
|
textColor: Color(0xffC9E7BB),
|
||||||
|
backgroundColor: Color(0xff4C5847)),
|
||||||
|
// ...add other color pairs with names...
|
||||||
|
];
|
|
@ -3,28 +3,37 @@ import 'dart:ui';
|
||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import '../definitions/ColorPairs.dart';
|
||||||
|
|
||||||
class PreferencesService {
|
class PreferencesService {
|
||||||
static const _keyColor1 = 'color1';
|
static const _keyColor1 = 'color1';
|
||||||
static const _keyColor2 = 'color2';
|
static const _keyColor2 = 'color2';
|
||||||
static const _keyDiaryEntries = 'diaryEntries';
|
static const _keyDiaryEntries = 'diaryEntries';
|
||||||
|
static const _keyPin = 'userPin';
|
||||||
|
static const _keyPinEnabled = 'pinEnabled';
|
||||||
|
|
||||||
// Load color preferences
|
// Helper method to save a ColorPair preference
|
||||||
Future<ColorPreference> loadColors() async {
|
Future<void> saveColorPair(ColorPair colorPair) async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString(
|
||||||
|
_keyColor1, colorPair.backgroundColor.value.toString());
|
||||||
|
await prefs.setString(_keyColor2, colorPair.textColor.value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to load the ColorPair preference
|
||||||
|
Future<ColorPair> loadColorPair() async {
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
final String? color1 = prefs.getString(_keyColor1);
|
final String? color1 = prefs.getString(_keyColor1);
|
||||||
final String? color2 = prefs.getString(_keyColor2);
|
final String? color2 = prefs.getString(_keyColor2);
|
||||||
|
|
||||||
return ColorPreference(
|
if (color1 != null && color2 != null) {
|
||||||
color1: color1 != null ? Color(int.parse(color1)) : null,
|
return ColorPair(
|
||||||
color2: color2 != null ? Color(int.parse(color2)) : null,
|
name: "Custom", // You might want to handle naming differently
|
||||||
|
textColor: Color(int.parse(color2)),
|
||||||
|
backgroundColor: Color(int.parse(color1)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return colorPairs[0]; // Return null if no color pair is set
|
||||||
// Save color preferences
|
|
||||||
Future<void> saveColors(Color color1, Color color2) async {
|
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
await prefs.setString(_keyColor1, color1.value.toString());
|
|
||||||
await prefs.setString(_keyColor2, color2.value.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the diary entry for the current date
|
// Get the diary entry for the current date
|
||||||
|
@ -113,6 +122,42 @@ class PreferencesService {
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check PIN method
|
||||||
|
Future<bool> checkPin(int pin) async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
int savedPin = prefs.getInt(_keyPin) ?? -1; // Default to -1 if not set
|
||||||
|
return savedPin == pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if PIN is enabled
|
||||||
|
Future<bool> isPinEnabled() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
return prefs.getBool(_keyPinEnabled) ?? false; // Return false if not set
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable PIN
|
||||||
|
Future<void> enablePin() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
if (prefs.getInt(_keyPin) != null) {
|
||||||
|
// Ensure PIN exists before enabling
|
||||||
|
await prefs.setBool(_keyPinEnabled, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable PIN
|
||||||
|
Future<void> disablePin() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool(_keyPinEnabled, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper class to store color preferences
|
// Helper class to store color preferences
|
||||||
|
|
|
@ -5,11 +5,11 @@ class QuestionGenerator {
|
||||||
"Welche Begebenheit hat heute dein Herz am meisten erfreut?",
|
"Welche Begebenheit hat heute dein Herz am meisten erfreut?",
|
||||||
"Was war das Highlight deines Tages, das dir ein Lächeln geschenkt hat?",
|
"Was war das Highlight deines Tages, das dir ein Lächeln geschenkt hat?",
|
||||||
"Welche besondere Erfahrung heute hat dir neue Energie und Freude gebracht?",
|
"Welche besondere Erfahrung heute hat dir neue Energie und Freude gebracht?",
|
||||||
"gut?",
|
"how fullfilled do you feel today?",
|
||||||
"Wie gehts?",
|
"how fullfilled do you feel today?",
|
||||||
"What's up?",
|
"how fullfilled do you feel today?",
|
||||||
"How arr you",
|
"how fullfilled do you feel today?",
|
||||||
"You ok?",
|
"how fullfilled do you feel today?",
|
||||||
];
|
];
|
||||||
|
|
||||||
String getQuestionByDate(DateTime date) {
|
String getQuestionByDate(DateTime date) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:moody/utils/definitions/ColorPairs.dart';
|
||||||
|
import 'package:moody/utils/logic/PreferencesService.dart';
|
||||||
|
|
||||||
class CustomBottomNavigationBar extends StatefulWidget {
|
class CustomBottomNavigationBar extends StatefulWidget {
|
||||||
final int initialSelectedIndex;
|
final int initialSelectedIndex;
|
||||||
|
@ -47,6 +49,28 @@ class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<ColorPair>(
|
||||||
|
future:
|
||||||
|
PreferencesService().loadColorPair(), // Async loading of the color
|
||||||
|
builder: (BuildContext context, AsyncSnapshot<ColorPair> snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
// When data is loaded
|
||||||
|
Color backgroundColor =
|
||||||
|
snapshot.data!.backgroundColor; // Use loaded background color
|
||||||
|
return buildNavigationBar(backgroundColor);
|
||||||
|
} else {
|
||||||
|
// While loading or if no data, show default or loading indicator
|
||||||
|
return buildNavigationBar(
|
||||||
|
Colors.white); // Default color or loading indicator
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildNavigationBar(Color backgroundColor) {
|
||||||
|
Future<ColorPair> globalColors = PreferencesService().loadColorPair();
|
||||||
return Container(
|
return Container(
|
||||||
width: 175,
|
width: 175,
|
||||||
margin: EdgeInsets.only(left: 130, right: 130, bottom: 30),
|
margin: EdgeInsets.only(left: 130, right: 130, bottom: 30),
|
||||||
|
@ -77,22 +101,25 @@ class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> {
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_buildNavItem(Image.asset('assets/icons/icon-analyze.png'), 0),
|
_buildNavItem(Image.asset('assets/icons/icon-analyze.png'), 0,
|
||||||
_buildNavItem(Image.asset('assets/icons/icon-logo.png'), 1),
|
backgroundColor),
|
||||||
_buildNavItem(Image.asset('assets/icons/icon-settings.png'), 2),
|
_buildNavItem(
|
||||||
|
Image.asset('assets/icons/icon-logo.png'), 1, backgroundColor),
|
||||||
|
_buildNavItem(Image.asset('assets/icons/icon-settings.png'), 2,
|
||||||
|
backgroundColor),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildNavItem(Image icon, int index) {
|
Widget _buildNavItem(Image icon, int index, Color selectedColor) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 40,
|
height: 40,
|
||||||
width: 40,
|
width: 40,
|
||||||
decoration: _selectedIndex == index
|
decoration: _selectedIndex == index
|
||||||
? BoxDecoration(
|
? BoxDecoration(
|
||||||
color: Colors.lightGreen,
|
color: selectedColor,
|
||||||
borderRadius: BorderRadius.circular(40),
|
borderRadius: BorderRadius.circular(40),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
|
|
@ -2,14 +2,13 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:moody/utils/logic/QuestionGenerator.dart';
|
import 'package:moody/utils/logic/QuestionGenerator.dart';
|
||||||
|
|
||||||
import '../CirclePainter.dart';
|
|
||||||
|
|
||||||
class QuestionSliderWidget extends StatefulWidget {
|
class QuestionSliderWidget extends StatefulWidget {
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
final String questionText;
|
final String questionText;
|
||||||
final double initialSliderValue;
|
final double initialSliderValue;
|
||||||
final bool isSliderEnabled;
|
final bool isSliderEnabled;
|
||||||
final ValueChanged<double> onSliderChanged;
|
final ValueChanged<SliderChangeData> onSliderChanged;
|
||||||
|
final ValueChanged<double> onSliderPositionChanged;
|
||||||
|
|
||||||
QuestionSliderWidget({
|
QuestionSliderWidget({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -18,6 +17,7 @@ class QuestionSliderWidget extends StatefulWidget {
|
||||||
required this.initialSliderValue,
|
required this.initialSliderValue,
|
||||||
required this.isSliderEnabled,
|
required this.isSliderEnabled,
|
||||||
required this.onSliderChanged,
|
required this.onSliderChanged,
|
||||||
|
required this.onSliderPositionChanged,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -25,34 +25,30 @@ class QuestionSliderWidget extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||||||
late double _sliderValue;
|
bool _showDragText = true;
|
||||||
bool _sliderChanged = false;
|
SliderChangeData _sliderData = SliderChangeData(0, 0);
|
||||||
QuestionGenerator generator = QuestionGenerator();
|
QuestionGenerator generator = QuestionGenerator();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_sliderValue = widget.initialSliderValue;
|
_sliderData.value = widget.initialSliderValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Expanded(
|
return Padding(
|
||||||
child: Stack(
|
padding: const EdgeInsets.fromLTRB(0, 150, 20, 0),
|
||||||
children: [
|
|
||||||
Positioned.fill(
|
|
||||||
top: 20,
|
|
||||||
left: _calculateSliderPosition(context, _sliderValue) - 60,
|
|
||||||
child: CustomPaint(
|
|
||||||
painter: CirclePainter(_sliderValue),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 150, 20, 20),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
// Date
|
// Date
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(30, 0, 0, 30),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
Text(
|
Text(
|
||||||
DateFormat('dd MM yyyy').format(widget.date),
|
DateFormat('dd MM yyyy').format(widget.date),
|
||||||
style: TextStyle(fontSize: 18),
|
style: TextStyle(fontSize: 18),
|
||||||
|
@ -62,10 +58,17 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||||||
generator.getQuestionByDate(widget.date),
|
generator.getQuestionByDate(widget.date),
|
||||||
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
// Slider and label
|
// Slider and label
|
||||||
SliderTheme(
|
Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(15, 0, 0, 15),
|
||||||
|
child: SliderTheme(
|
||||||
data: SliderTheme.of(context).copyWith(
|
data: SliderTheme.of(context).copyWith(
|
||||||
disabledThumbColor: Colors.amber,
|
disabledThumbColor: Colors.transparent,
|
||||||
activeTrackColor: Colors.black,
|
activeTrackColor: Colors.black,
|
||||||
trackShape: RectangularSliderTrackShape(),
|
trackShape: RectangularSliderTrackShape(),
|
||||||
inactiveTickMarkColor: Colors.red,
|
inactiveTickMarkColor: Colors.red,
|
||||||
|
@ -77,7 +80,7 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||||||
trackHeight: 2,
|
trackHeight: 2,
|
||||||
thumbColor: Colors.transparent,
|
thumbColor: Colors.transparent,
|
||||||
thumbShape: RoundSliderThumbShape(
|
thumbShape: RoundSliderThumbShape(
|
||||||
enabledThumbRadius: 30.0,
|
enabledThumbRadius: 10.0,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
disabledThumbRadius: 0),
|
disabledThumbRadius: 0),
|
||||||
rangeThumbShape: RoundRangeSliderThumbShape(
|
rangeThumbShape: RoundRangeSliderThumbShape(
|
||||||
|
@ -86,36 +89,41 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Slider(
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
children: [
|
|
||||||
Slider(
|
|
||||||
min: 0.0,
|
min: 0.0,
|
||||||
max: 100.0,
|
max: 100.0,
|
||||||
value: _sliderValue,
|
value: _sliderData.value,
|
||||||
onChanged: widget.isSliderEnabled
|
onChanged: widget.isSliderEnabled
|
||||||
? (value) {
|
? (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_sliderValue = value;
|
_sliderData.position =
|
||||||
_sliderChanged = true;
|
_calculateSliderPosition(context, value);
|
||||||
|
_sliderData.value = value;
|
||||||
|
_showDragText = false;
|
||||||
});
|
});
|
||||||
widget.onSliderChanged(value);
|
widget.onSliderChanged(SliderChangeData(
|
||||||
|
_sliderData.value, _sliderData.position));
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
left: _calculateSliderPosition(context, _sliderValue),
|
left: _calculateSliderPosition(context, _sliderData.value),
|
||||||
child: Text(
|
child: IgnorePointer(
|
||||||
"${_sliderValue.toStringAsFixed(0)}%",
|
child: _showDragText
|
||||||
style: TextStyle(fontSize: 20), // Size increased by 2
|
? Text(
|
||||||
|
"Drag Me -->",
|
||||||
|
style: TextStyle(fontSize: 16),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
"${_sliderData.value.toStringAsFixed(0)}%",
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -128,3 +136,10 @@ class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||||||
return (sliderWidth - thumbWidth) * value / 100.0 + thumbWidth / 2;
|
return (sliderWidth - thumbWidth) * value / 100.0 + thumbWidth / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SliderChangeData {
|
||||||
|
double value;
|
||||||
|
double position; // Additional data you might want to include
|
||||||
|
|
||||||
|
SliderChangeData(this.value, this.position);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../utils/definitions/ColorPairs.dart';
|
||||||
|
import '../../utils/logic/PreferencesService.dart';
|
||||||
|
import '../../utils/widgets/BottomNavigationWidget.dart';
|
||||||
|
|
||||||
|
// ...Include PreferencesService and other necessary imports
|
||||||
|
|
||||||
|
class ColorPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_ColorPageState createState() => _ColorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorPageState extends State<ColorPage> {
|
||||||
|
int? selectedColorIndex; // Index of the selected color
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadSelectedColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load selected color from preferences
|
||||||
|
void _loadSelectedColor() async {
|
||||||
|
ColorPair? savedColorPair = await PreferencesService().loadColorPair();
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
if (index != -1) {
|
||||||
|
setState(() {
|
||||||
|
selectedColorIndex = index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no color is selected, default to the first one
|
||||||
|
setState(() {
|
||||||
|
selectedColorIndex = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(30, 150, 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)),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
Text("change color", style: TextStyle(fontSize: 24)),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
Wrap(
|
||||||
|
spacing: 15, // space between circles horizontally
|
||||||
|
runSpacing: 15, // space between circles vertically
|
||||||
|
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)),
|
||||||
|
),
|
||||||
|
Text("Wish you a color!", style: TextStyle(color: Colors.grey)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||||
|
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to build a single color circle
|
||||||
|
Widget buildColorCircle(int index) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
setState(() {
|
||||||
|
selectedColorIndex = index; // Set selected color
|
||||||
|
});
|
||||||
|
await PreferencesService().saveColorPair(colorPairs[index]);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
padding: EdgeInsets.all(10), // Padding for inner circle effect
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colorPairs[index].backgroundColor,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:moody/utils/widgets/QuestionSliderWidget.dart';
|
import 'package:moody/utils/widgets/QuestionSliderWidget.dart';
|
||||||
|
|
||||||
|
import '../../utils/CirclePainter.dart';
|
||||||
|
import '../../utils/definitions/ColorPairs.dart';
|
||||||
import '../../utils/logic/PreferencesService.dart';
|
import '../../utils/logic/PreferencesService.dart';
|
||||||
|
|
||||||
class FirstPage extends StatefulWidget {
|
class FirstPage extends StatefulWidget {
|
||||||
|
@ -10,10 +12,28 @@ class FirstPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FirstPageState extends State<FirstPage> {
|
class _FirstPageState extends State<FirstPage> {
|
||||||
|
SliderChangeData sliderData = SliderChangeData(0, 0);
|
||||||
double _sliderValue = 0.0;
|
double _sliderValue = 0.0;
|
||||||
bool _sliderChanged = false;
|
bool _sliderChanged = false;
|
||||||
PreferencesService _prefsService = PreferencesService();
|
PreferencesService _prefsService = PreferencesService();
|
||||||
|
|
||||||
|
Color backgroundColor = Colors.lightGreenAccent;
|
||||||
|
Color textColor = Colors.black;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadColor() async {
|
||||||
|
ColorPair colorPair = await PreferencesService().loadColorPair();
|
||||||
|
setState(() {
|
||||||
|
backgroundColor = colorPair.backgroundColor;
|
||||||
|
textColor = colorPair.textColor;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _saveEntry() async {
|
void _saveEntry() async {
|
||||||
try {
|
try {
|
||||||
List<String> texts = [];
|
List<String> texts = [];
|
||||||
|
@ -32,41 +52,54 @@ class _FirstPageState extends State<FirstPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return backgroundColor == Colors.lightGreenAccent
|
||||||
|
? CircularProgressIndicator() // Show loading indicator while color is null
|
||||||
|
: MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
// Background circle
|
// Background circle
|
||||||
/*Positioned.fill(
|
Positioned.fill(
|
||||||
|
top: 15,
|
||||||
|
left: sliderData.position - 70,
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: CirclePainter(_sliderValue),
|
painter:
|
||||||
|
CirclePainter(sliderData.value, backgroundColor),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),*/
|
|
||||||
// Main content
|
// Main content
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
// Date
|
// Date
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
QuestionSliderWidget(
|
QuestionSliderWidget(
|
||||||
|
onSliderPositionChanged: (value) {
|
||||||
|
print("sliderposchanged");
|
||||||
|
},
|
||||||
date: DateTime.now(),
|
date: DateTime.now(),
|
||||||
questionText: "How are you today",
|
questionText: "",
|
||||||
initialSliderValue: 0,
|
initialSliderValue: 0,
|
||||||
isSliderEnabled: true,
|
isSliderEnabled: true,
|
||||||
onSliderChanged: (value) {
|
onSliderChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_sliderValue = value;
|
sliderData = value;
|
||||||
|
if (!_sliderChanged) _sliderChanged = true;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
// Why? button
|
],
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
context.go('/write', extra: _sliderValue);
|
|
||||||
|
|
||||||
// Implement your why? functionality here
|
|
||||||
},
|
|
||||||
child: Text("Why?"),
|
|
||||||
),
|
),
|
||||||
|
// Why? button
|
||||||
|
_sliderChanged
|
||||||
|
? TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.go('/write', extra: sliderData.value);
|
||||||
|
},
|
||||||
|
child: Text("warum?"),
|
||||||
|
)
|
||||||
|
: SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// Skip/Save button
|
// Skip/Save button
|
||||||
|
@ -78,7 +111,7 @@ class _FirstPageState extends State<FirstPage> {
|
||||||
print(_sliderChanged);
|
print(_sliderChanged);
|
||||||
if (_sliderChanged) {
|
if (_sliderChanged) {
|
||||||
_saveEntry();
|
_saveEntry();
|
||||||
context.go('/home', extra: _sliderValue);
|
context.go('/home', extra: sliderData.value);
|
||||||
} else {
|
} else {
|
||||||
context.go('/home', extra: 0);
|
context.go('/home', extra: 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class _DragWidgetState extends State<DragWidget> {
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: CirclePainter(_sliderValue),
|
painter: CirclePainter(_sliderValue, Colors.red),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
|
|
|
@ -68,20 +68,23 @@ class _HomePageState extends State<HomePage> {
|
||||||
// Background circle
|
// Background circle
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: CirclePainter(_sliderValue),
|
painter: CirclePainter(_sliderValue, Colors.orange),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
QuestionSliderWidget(
|
QuestionSliderWidget(
|
||||||
|
onSliderPositionChanged: (value) {
|
||||||
|
print("sliderposchanged");
|
||||||
|
},
|
||||||
date: DateTime.now(),
|
date: DateTime.now(),
|
||||||
questionText: 'this is how it is:',
|
questionText: 'this is how it is:',
|
||||||
initialSliderValue: _sliderValue,
|
initialSliderValue: _sliderValue,
|
||||||
isSliderEnabled: true,
|
isSliderEnabled: true,
|
||||||
onSliderChanged: (value) {
|
onSliderChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_sliderValue = value;
|
_sliderValue = value.value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,102 +1,124 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../../utils/widgets/BottomNavigationWidget.dart';
|
import '../../utils/widgets/BottomNavigationWidget.dart';
|
||||||
|
import 'widgets/CustomDivider.dart';
|
||||||
|
import 'widgets/SetPinPopup.dart';
|
||||||
|
import 'widgets/TextSwitchContainer.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: ListView(
|
backgroundColor: Color(0xffeeeeee),
|
||||||
|
body: Container(
|
||||||
|
padding: EdgeInsets.only(bottom: 0),
|
||||||
|
margin: const EdgeInsets.fromLTRB(30, 30, 30, 0),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
const SizedBox(
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
height: 100,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Settings section
|
// Settings section
|
||||||
ListTile(
|
|
||||||
title:
|
|
||||||
Text('settings', style: TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('change color'),
|
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
|
||||||
Divider(),
|
|
||||||
// Community section
|
|
||||||
ListTile(
|
|
||||||
title: Text('notifications'),
|
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
|
||||||
Divider(),
|
|
||||||
// Community section
|
|
||||||
ListTile(
|
|
||||||
title: Text('set pin'),
|
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
|
||||||
Divider(),
|
|
||||||
// Community section
|
|
||||||
ListTile(
|
|
||||||
title: Text('export your data'),
|
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
margin: EdgeInsets.only(bottom: 10),
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text('settings',
|
||||||
|
style:
|
||||||
|
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
|
||||||
),
|
),
|
||||||
ListTile(
|
TextSwitchContainer(
|
||||||
title: Text('community',
|
leftText: "change color",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
onTap: () => context.go("/color"),
|
||||||
),
|
),
|
||||||
ListTile(
|
CustomDivider(),
|
||||||
title: Text('join our discord'),
|
TextSwitchContainer(
|
||||||
trailing: Text('fulfilled'),
|
leftText: "pin",
|
||||||
onTap: () => {}, // Implement your logic
|
hasSwitch: true,
|
||||||
|
onTap: () => {showSetPinPopup(context)},
|
||||||
|
onSwitchToggle: (value) => print('Switch toggled: $value'),
|
||||||
),
|
),
|
||||||
Divider(),
|
CustomDivider(),
|
||||||
//
|
TextSwitchContainer(
|
||||||
ListTile(
|
leftText: "your data",
|
||||||
title: Text('our instagram'),
|
onTap: () => print('Container tapped'),
|
||||||
trailing: Text('@get_fulfilled'),
|
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
),
|
||||||
Divider(),
|
// Community section
|
||||||
//
|
Padding(
|
||||||
ListTile(
|
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
|
||||||
title: Text('share fulfilled with your loved ones'),
|
child: Container(
|
||||||
onTap: () => {}, // Implement your logic
|
alignment: Alignment.topLeft,
|
||||||
|
margin: EdgeInsets.only(bottom: 10),
|
||||||
|
child: Text('community',
|
||||||
|
style:
|
||||||
|
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
|
||||||
),
|
),
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
TextSwitchContainer(
|
||||||
title: Text('humans behind fulfilled',
|
leftText: "join our discord",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
rightText: "fullfilled",
|
||||||
|
onTap: () => print('Container tapped'),
|
||||||
),
|
),
|
||||||
ListTile(
|
CustomDivider(),
|
||||||
title: Text('about us'),
|
TextSwitchContainer(
|
||||||
onTap: () => {}, // Implement your logic
|
leftText: "our instagram",
|
||||||
|
rightText: "@get.fullfilled",
|
||||||
|
onTap: () => print('Container tapped'),
|
||||||
),
|
),
|
||||||
Divider(),
|
CustomDivider(),
|
||||||
//
|
TextSwitchContainer(
|
||||||
ListTile(
|
leftText: "share fullfilled with your loved ones",
|
||||||
title: Text('support us'),
|
onTap: () => print('Container tapped'),
|
||||||
onTap: () => {}, // Implement your logic
|
|
||||||
),
|
),
|
||||||
Divider(),
|
Padding(
|
||||||
//
|
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
|
||||||
ListTile(
|
child: Container(
|
||||||
title: Text('give feedback'),
|
alignment: Alignment.topLeft,
|
||||||
onTap: () => {}, // Implement your logic
|
child: Text('humans behind fullfilled',
|
||||||
|
style:
|
||||||
|
TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSwitchContainer(
|
||||||
|
leftText: "about us",
|
||||||
|
onTap: () => print('Container tapped'),
|
||||||
|
),
|
||||||
|
CustomDivider(),
|
||||||
|
TextSwitchContainer(
|
||||||
|
leftText: "support us",
|
||||||
|
onTap: () => print('Container tapped'),
|
||||||
|
),
|
||||||
|
CustomDivider(),
|
||||||
|
TextSwitchContainer(
|
||||||
|
leftText: "give feedback",
|
||||||
|
onTap: () => print('Container tapped'),
|
||||||
),
|
),
|
||||||
Divider(),
|
|
||||||
//
|
//
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('imprint & privacy policy',
|
title: Text('imprint & privacy policy',
|
||||||
style: TextStyle(color: Colors.grey)),
|
style: TextStyle(color: Colors.grey, fontSize: 15)),
|
||||||
onTap: () => {}, // Implement your logic
|
onTap: () => {}, // Implement your logic
|
||||||
),
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 150,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||||
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 3),
|
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSetPinPopup(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return SetPinPopup();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CustomDivider extends StatelessWidget {
|
||||||
|
const CustomDivider({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Divider(
|
||||||
|
color: Colors.grey.shade300,
|
||||||
|
thickness: 1, // Set thickness to 1px
|
||||||
|
height: 1, // Set height to 1px to reduce padding
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import '../../../utils/logic/PreferencesService.dart'; // For HapticFeedback
|
||||||
|
|
||||||
|
// ...Include PreferencesService and other necessary imports
|
||||||
|
|
||||||
|
class SetPinPopup extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_SetPinPopupState createState() => _SetPinPopupState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SetPinPopupState extends State<SetPinPopup> {
|
||||||
|
String _pin = '';
|
||||||
|
String _confirmedPin = '';
|
||||||
|
bool _isSettingPin =
|
||||||
|
true; // True if setting the PIN, false if confirming the PIN
|
||||||
|
|
||||||
|
static const int pinLength = 4;
|
||||||
|
|
||||||
|
// Include the methods from PinInputScreen here
|
||||||
|
List<Widget> _buildNumberPad() {
|
||||||
|
List<int> numbers = List.generate(9, (index) => index + 1);
|
||||||
|
List<Widget> rows = [];
|
||||||
|
|
||||||
|
// First three rows (1-9)
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
rows.add(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: numbers.skip(i * 3).take(3).map((number) {
|
||||||
|
return _buildNumberButton(number);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last row with 0
|
||||||
|
rows.add(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(width: 70), // Empty container to align 0 in center
|
||||||
|
_buildNumberButton(0),
|
||||||
|
Container(width: 70), // Empty container to align 0 in center
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNumberButton(int number) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => _onNumberTap(number),
|
||||||
|
onTapDown: (_) =>
|
||||||
|
HapticFeedback.lightImpact(), // Cool haptic feedback on tap
|
||||||
|
child: Container(
|
||||||
|
width: 70,
|
||||||
|
height: 70,
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(color: Colors.black),
|
||||||
|
borderRadius: BorderRadius.circular(35),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
number.toString(),
|
||||||
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onNumberTap(int number) {
|
||||||
|
setState(() {
|
||||||
|
if (_isSettingPin) {
|
||||||
|
_pin += number.toString();
|
||||||
|
} else {
|
||||||
|
_confirmedPin += number.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((_isSettingPin && _pin.length == pinLength) ||
|
||||||
|
(!_isSettingPin && _confirmedPin.length == pinLength)) {
|
||||||
|
if (!_isSettingPin && _pin == _confirmedPin) {
|
||||||
|
// Call setPin and enablePin methods, assuming they are async
|
||||||
|
PreferencesService().setPin(int.parse(_pin));
|
||||||
|
PreferencesService().enablePin();
|
||||||
|
Navigator.of(context).pop(); // Close the dialog
|
||||||
|
} else if (!_isSettingPin && _pin != _confirmedPin) {
|
||||||
|
// PINs don't match, reset and let the user set the PIN again
|
||||||
|
setState(() {
|
||||||
|
_pin = '';
|
||||||
|
_confirmedPin = '';
|
||||||
|
_isSettingPin = true; // Reset back to setting PIN
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Move to confirming the PIN
|
||||||
|
setState(() {
|
||||||
|
_isSettingPin = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dialog(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
child: BackdropFilter(
|
||||||
|
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
|
||||||
|
child: Container(
|
||||||
|
height: 600,
|
||||||
|
width: 400,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(50))),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(_isSettingPin ? 'Set a PIN' : 'Repeat PIN',
|
||||||
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: List.generate(pinLength, (index) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.all(4),
|
||||||
|
width: 15,
|
||||||
|
height: 15,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
(_isSettingPin ? _pin.length : _confirmedPin.length) >
|
||||||
|
index
|
||||||
|
? Colors.black
|
||||||
|
: Colors.transparent,
|
||||||
|
border: Border.all(color: Colors.grey),
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
..._buildNumberPad(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TextSwitchContainer extends StatefulWidget {
|
||||||
|
final String leftText;
|
||||||
|
final String? rightText;
|
||||||
|
final bool hasSwitch;
|
||||||
|
final Function onTap;
|
||||||
|
final Function(bool)? onSwitchToggle;
|
||||||
|
|
||||||
|
TextSwitchContainer({
|
||||||
|
required this.leftText,
|
||||||
|
this.rightText,
|
||||||
|
this.hasSwitch = false,
|
||||||
|
required this.onTap,
|
||||||
|
this.onSwitchToggle,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_TextSwitchContainerState createState() => _TextSwitchContainerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TextSwitchContainerState extends State<TextSwitchContainer> {
|
||||||
|
bool switchValue = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => widget.onTap(),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 20),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.leftText,
|
||||||
|
style: TextStyle(fontSize: 18),
|
||||||
|
),
|
||||||
|
if (widget.hasSwitch)
|
||||||
|
CupertinoSwitch(
|
||||||
|
trackColor: Colors.white,
|
||||||
|
thumbColor: switchValue ? Colors.lightGreen : Colors.grey,
|
||||||
|
value: switchValue,
|
||||||
|
onChanged: (newValue) {
|
||||||
|
setState(() {
|
||||||
|
switchValue = newValue;
|
||||||
|
widget.onSwitchToggle?.call(newValue);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
activeColor: Colors.white, // Active (ON) color
|
||||||
|
// CupertinoSwitch doesn't allow inactive thumb color customization by default
|
||||||
|
// Track color changes with the active color
|
||||||
|
)
|
||||||
|
else if (widget.rightText != null)
|
||||||
|
Text(
|
||||||
|
widget.rightText!,
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,184 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
|
import '../../utils/logic/PreferencesService.dart'; // For Haptic Feedback
|
||||||
|
|
||||||
|
class StartPage extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'PIN Input',
|
||||||
|
home: PinInputScreen(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PinInputScreen extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_PinInputScreenState createState() => _PinInputScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PinInputScreenState extends State<PinInputScreen> {
|
||||||
|
String _pin = '';
|
||||||
|
static const int pinLength = 4;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_checkPinStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _checkPinStatus() async {
|
||||||
|
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.
|
||||||
|
Future.microtask(() => context.go("/first"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method would be your actual method for checking the pin
|
||||||
|
// Replace with your actual method from PreferencesService
|
||||||
|
Future<bool> checkPin(int pin) async {
|
||||||
|
bool pinRight = await PreferencesService().checkPin(pin);
|
||||||
|
return pinRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onNumberTap(int number) {
|
||||||
|
if (_pin.length < pinLength) {
|
||||||
|
setState(() {
|
||||||
|
_pin += number.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_pin.length == pinLength) {
|
||||||
|
_validatePin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _validatePin() async {
|
||||||
|
bool correct = await checkPin(int.parse(_pin));
|
||||||
|
if (correct) {
|
||||||
|
print("Right");
|
||||||
|
context.go("/first");
|
||||||
|
// Perform any actions you need on successful pin entry
|
||||||
|
} else {
|
||||||
|
// Handle wrong pin entry, e.g., reset pin, show error, etc.
|
||||||
|
print("Wrong PIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resetting the PIN for this example, you might want to do this differently
|
||||||
|
setState(() {
|
||||||
|
_pin = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.grey.shade200, // Light gray background
|
||||||
|
body: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [Colors.grey, Colors.red.shade100],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
height: 600,
|
||||||
|
width: 400,
|
||||||
|
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)),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: List.generate(pinLength, (index) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.all(4),
|
||||||
|
width: 15,
|
||||||
|
height: 15,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _pin.length > index
|
||||||
|
? Colors.black
|
||||||
|
: Colors.transparent,
|
||||||
|
border: Border.all(color: Colors.grey),
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
..._buildNumberPad(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildNumberPad() {
|
||||||
|
List<int> numbers = List.generate(9, (index) => index + 1);
|
||||||
|
List<Widget> rows = [];
|
||||||
|
|
||||||
|
// First three rows (1-9)
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
rows.add(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: numbers.skip(i * 3).take(3).map((number) {
|
||||||
|
return _buildNumberButton(number);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last row with 0
|
||||||
|
rows.add(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(width: 70), // Empty container to align 0 in center
|
||||||
|
_buildNumberButton(0),
|
||||||
|
Container(width: 70), // Empty container to align 0 in center
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNumberButton(int number) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => _onNumberTap(number),
|
||||||
|
onTapDown: (_) =>
|
||||||
|
HapticFeedback.lightImpact(), // Cool haptic feedback on tap
|
||||||
|
child: Container(
|
||||||
|
width: 70,
|
||||||
|
height: 70,
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.black),
|
||||||
|
borderRadius: BorderRadius.circular(35),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
number.toString(),
|
||||||
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,25 +21,24 @@ class StatisticPage extends StatelessWidget {
|
||||||
"browse your memories!",
|
"browse your memories!",
|
||||||
style: TextStyle(fontSize: 24),
|
style: TextStyle(fontSize: 24),
|
||||||
),
|
),
|
||||||
Container(
|
Expanded(
|
||||||
height: 650,
|
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
|
||||||
child: CalendarWidget(currentDate: DateTime.now())),
|
|
||||||
Container(
|
|
||||||
child: CalendarWidget(
|
|
||||||
currentDate: DateTime(
|
|
||||||
DateTime.now().year,
|
|
||||||
DateTime.now().month - 1,
|
|
||||||
DateTime.now().day))),
|
|
||||||
Container(
|
Container(
|
||||||
child: CalendarWidget(
|
child: CalendarWidget(
|
||||||
currentDate: DateTime(
|
currentDate: DateTime(
|
||||||
DateTime.now().year,
|
DateTime.now().year,
|
||||||
DateTime.now().month - 2,
|
DateTime.now().month - 2,
|
||||||
DateTime.now().day))),
|
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(
|
SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import '../../../utils/definitions/ColorPairs.dart';
|
||||||
|
import '../../../utils/logic/PreferencesService.dart'; // Correct the path as necessary
|
||||||
|
|
||||||
class CalendarWidget extends StatefulWidget {
|
class CalendarWidget extends StatefulWidget {
|
||||||
final DateTime currentDate;
|
final DateTime currentDate;
|
||||||
|
|
||||||
|
@ -14,12 +15,32 @@ class CalendarWidget extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CalendarWidgetState extends State<CalendarWidget> {
|
class _CalendarWidgetState extends State<CalendarWidget> {
|
||||||
late List<DateTime> dateList;
|
List<DateTime> dateList = []; // Initialized immediately as an empty list
|
||||||
|
Map<String, DiaryEntry?> diaryEntries = {}; // Holds diary entries by date
|
||||||
|
late ColorPair currentColorPair; // Holds the current color pair
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
dateList = _generateDateList(widget.currentDate);
|
dateList = _generateDateList(widget.currentDate); // Ensured initialization
|
||||||
|
_loadColorPairAndDiaryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadColorPairAndDiaryData() async {
|
||||||
|
// Load color pair
|
||||||
|
currentColorPair =
|
||||||
|
await PreferencesService().loadColorPair() ?? colorPairs[0];
|
||||||
|
|
||||||
|
// Generate date list
|
||||||
|
//dateList = _generateDateList(widget.currentDate);
|
||||||
|
|
||||||
|
// Load diary entries for each date
|
||||||
|
for (DateTime date in dateList) {
|
||||||
|
DiaryEntry? entry = await PreferencesService().getDiaryEntryByDate(date);
|
||||||
|
String key = DateFormat('yyyy-MM-dd').format(date);
|
||||||
|
diaryEntries[key] = entry;
|
||||||
|
}
|
||||||
|
setState(() {}); // Update the state to reflect new data
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DateTime> _generateDateList(DateTime date) {
|
List<DateTime> _generateDateList(DateTime date) {
|
||||||
|
@ -52,44 +73,65 @@ class _CalendarWidgetState extends State<CalendarWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
print(dateList.length);
|
|
||||||
double addon = dateList.length > 35 ? 50 : 0;
|
double addon = dateList.length > 35 ? 50 : 0;
|
||||||
|
String monthName =
|
||||||
|
DateFormat("MMMM yyyy").format(widget.currentDate); // For month header
|
||||||
|
|
||||||
|
return FutureBuilder<ColorPair>(
|
||||||
|
future: PreferencesService().loadColorPair(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
ColorPair colorPair = snapshot.data!;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
height: 360 + addon,
|
||||||
border: Border(
|
child: Column(
|
||||||
bottom: BorderSide(
|
children: [
|
||||||
color: Colors.black.withOpacity(0.3),
|
Padding(
|
||||||
style: BorderStyle.solid,
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||||
width: 2))),
|
child: Text(monthName,
|
||||||
height: 300 + addon,
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold)), // Month Header
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(25, 0, 25, 0),
|
padding: const EdgeInsets.fromLTRB(25, 0, 25, 0),
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
physics:
|
physics: NeverScrollableScrollPhysics(),
|
||||||
NeverScrollableScrollPhysics(), // Disable scrolling for GridView
|
|
||||||
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 7,
|
crossAxisCount: 7,
|
||||||
),
|
),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
DateTime date = dateList[index];
|
DateTime date = dateList[index];
|
||||||
bool isCurrentMonth = date.month == widget.currentDate.month;
|
bool isCurrentMonth =
|
||||||
double outerRadius = 25; // Fixed outer radius
|
date.month == widget.currentDate.month;
|
||||||
double innerRadius = Random().nextDouble() * outerRadius;
|
|
||||||
double opacity = isCurrentMonth ? 1.0 : 0.15;
|
double opacity = isCurrentMonth ? 1.0 : 0.15;
|
||||||
|
|
||||||
|
// Fetching diary entry percentage value
|
||||||
|
DiaryEntry? entry =
|
||||||
|
diaryEntries[DateFormat('yyyy-MM-dd').format(date)];
|
||||||
|
double fillPercentage =
|
||||||
|
entry != null ? entry.percentValue / 100.0 : 0.0;
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () => {
|
onTap: () => {context.go('/entry', extra: date)},
|
||||||
context.go('/entry', extra: date)
|
|
||||||
}, // Using the callback here
|
|
||||||
child: Container(
|
child: Container(
|
||||||
width: outerRadius * 2,
|
width: 50,
|
||||||
height: outerRadius * 2,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(color: Colors.black, width: 2),
|
border:
|
||||||
color: isCurrentMonth
|
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
|
||||||
|
: isCurrentMonth
|
||||||
? Colors.transparent
|
? Colors.transparent
|
||||||
: Colors.grey.withOpacity(opacity),
|
: Colors.grey.withOpacity(opacity),
|
||||||
),
|
),
|
||||||
|
@ -97,8 +139,10 @@ class _CalendarWidgetState extends State<CalendarWidget> {
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
CircleWidget(
|
CircleWidget(
|
||||||
radius: innerRadius,
|
radius: 25 * fillPercentage,
|
||||||
color: Colors.lightGreenAccent.withOpacity(0.75)),
|
color: fillPercentage > 0
|
||||||
|
? colorPair.backgroundColor
|
||||||
|
: Colors.teal.withOpacity(opacity)),
|
||||||
Text(
|
Text(
|
||||||
DateFormat("d").format(date),
|
DateFormat("d").format(date),
|
||||||
style: TextStyle(color: Colors.black),
|
style: TextStyle(color: Colors.black),
|
||||||
|
@ -112,6 +156,45 @@ class _CalendarWidgetState extends State<CalendarWidget> {
|
||||||
itemCount: dateList.length,
|
itemCount: dateList.length,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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)),
|
||||||
|
Text(
|
||||||
|
DateFormat("d").format(date),
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ class _WritePageState extends State<WritePage> {
|
||||||
// Background circle
|
// Background circle
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: CirclePainter(_sliderValue),
|
painter: CirclePainter(_sliderValue, Colors.yellowAccent),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Main content
|
// Main content
|
||||||
|
@ -70,13 +70,16 @@ class _WritePageState extends State<WritePage> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
QuestionSliderWidget(
|
QuestionSliderWidget(
|
||||||
|
onSliderPositionChanged: (value) {
|
||||||
|
print("sliderposchanged");
|
||||||
|
},
|
||||||
date: DateTime.now(),
|
date: DateTime.now(),
|
||||||
questionText: "How are you today",
|
questionText: "How are you today",
|
||||||
initialSliderValue: 0,
|
initialSliderValue: 0,
|
||||||
isSliderEnabled: true,
|
isSliderEnabled: true,
|
||||||
onSliderChanged: (value) {
|
onSliderChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_sliderValue = value;
|
// _sliderValue = value;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|
Loading…
Reference in New Issue