Enhance: Google Photos integration, refinement of Schedule/Todo lists and API fixes
This commit is contained in:
@@ -1559,10 +1559,14 @@ class _TodoManagerTabState extends State<TodoManagerTab> {
|
||||
),
|
||||
),
|
||||
subtitle: todo.dueDate != null
|
||||
? Text(
|
||||
todo.dueDate!.toIso8601String().split('T')[0],
|
||||
style:
|
||||
const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
? Builder(
|
||||
builder: (context) {
|
||||
final dueDate = todo.dueDate!;
|
||||
return Text(
|
||||
dueDate.toIso8601String().split('T')[0],
|
||||
style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
);
|
||||
},
|
||||
)
|
||||
: null,
|
||||
trailing: Row(
|
||||
|
||||
@@ -78,13 +78,13 @@ class PhotoService {
|
||||
}
|
||||
|
||||
Future<String> getGoogleAuthUrl() async {
|
||||
final data = await _client.get("${ApiConfig.photos}/auth/url");
|
||||
final data = await _client.getMap("${ApiConfig.photos}/auth/url");
|
||||
return data["url"] as String;
|
||||
}
|
||||
|
||||
Future<bool> getGoogleStatus() async {
|
||||
try {
|
||||
final data = await _client.get("${ApiConfig.photos}/status");
|
||||
final data = await _client.getMap("${ApiConfig.photos}/status");
|
||||
return data["connected"] as bool? ?? false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
@@ -92,6 +92,6 @@ class PhotoService {
|
||||
}
|
||||
|
||||
Future<void> disconnectGoogle() async {
|
||||
await _client.get("${ApiConfig.photos}/disconnect");
|
||||
await _client.getMap("${ApiConfig.photos}/disconnect");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,23 @@ class TodoService {
|
||||
|
||||
Future<List<TodoItem>> fetchTodayTodos() async {
|
||||
if (ApiConfig.useMockData) {
|
||||
final today = DateTime.now();
|
||||
return MockDataStore.todos.where((todo) => todo.dueDate != null).where((
|
||||
todo,
|
||||
) {
|
||||
final date = todo.dueDate!;
|
||||
return date.year == today.year &&
|
||||
date.month == today.month &&
|
||||
date.day == today.day;
|
||||
final now = DateTime.now();
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
final tomorrow = today.add(const Duration(days: 1));
|
||||
|
||||
return MockDataStore.todos.where((todo) {
|
||||
if (todo.completed) {
|
||||
// If completed, only show if it was due today
|
||||
if (todo.dueDate == null) return false;
|
||||
return todo.dueDate!.isAfter(today.subtract(const Duration(milliseconds: 1))) &&
|
||||
todo.dueDate!.isBefore(tomorrow);
|
||||
}
|
||||
|
||||
// If not completed:
|
||||
// 1. No due date -> show
|
||||
// 2. Due today or before -> show
|
||||
if (todo.dueDate == null) return true;
|
||||
return todo.dueDate!.isBefore(tomorrow);
|
||||
}).toList();
|
||||
}
|
||||
final data = await _client.getList("${ApiConfig.todos}/today");
|
||||
|
||||
@@ -112,8 +112,8 @@ class _ScheduleListWidgetState extends State<ScheduleListWidget> {
|
||||
final endOfWeek = startOfWeek.add(const Duration(days: 6, hours: 23, minutes: 59, seconds: 59));
|
||||
|
||||
final filteredSchedules = _schedules.where((item) {
|
||||
// Overlap check: schedule starts before week ends AND schedule ends after week starts
|
||||
return item.startDate.isBefore(endOfWeek) && item.endDate.isAfter(startOfWeek);
|
||||
// Overlap check: schedule starts before week ends AND schedule ends after or on today
|
||||
return item.startDate.isBefore(endOfWeek) && (item.endDate.isAtSameMomentAs(today) || item.endDate.isAfter(today));
|
||||
}).toList();
|
||||
|
||||
if (filteredSchedules.isEmpty) {
|
||||
|
||||
@@ -219,12 +219,7 @@ class _TodoListWidgetState extends State<TodoListWidget> {
|
||||
decorationColor: Colors.white54,
|
||||
),
|
||||
),
|
||||
subtitle: todo.dueDate != null && (todo.dueDate!.hour != 0 || todo.dueDate!.minute != 0)
|
||||
? Text(
|
||||
DateFormat('HH:mm').format(todo.dueDate!),
|
||||
style: const TextStyle(color: Colors.white54, fontSize: 12),
|
||||
)
|
||||
: null,
|
||||
subtitle: null,
|
||||
trailing: Checkbox(
|
||||
value: todo.completed,
|
||||
onChanged: (val) async {
|
||||
|
||||
Reference in New Issue
Block a user