Use new list/sheets api instead of paged one

This commit is contained in:
2024-12-21 17:51:16 +01:00
parent 4651d2a5b0
commit 854528128f
3 changed files with 90 additions and 55 deletions

View File

@@ -121,15 +121,9 @@ class ApiClient {
return null; return null;
} }
Future<List<Sheet>> fetchSheets({String sortBy = "last_opened desc"}) async { Future<List<Sheet>> fetchSheets() async {
try { try {
final bodyFormData = { final response = await get("/list/sheets");
"page": 1,
"limit": "1000",
"sort_by": sortBy,
};
final response = await postFormData("/sheets", jsonEncode(bodyFormData));
if (response == null) { if (response == null) {
return List.empty(); return List.empty();
@@ -138,7 +132,7 @@ class ApiClient {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
log("Data: $data"); log("Data: $data");
return (data['rows'] as List<dynamic>) return (data as List<dynamic>)
.map((sheet) => Sheet.fromJson(sheet as Map<String, dynamic>)) .map((sheet) => Sheet.fromJson(sheet as Map<String, dynamic>))
.toList(); .toList();
} else { } else {

View File

@@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sheetless/sheet_viewer_page.dart'; import 'package:sheetless/sheet_viewer_page.dart';
import 'package:sheetless/storage_helper.dart'; import 'package:sheetless/storage_helper.dart';
@@ -37,7 +39,9 @@ class _MyHomePageState extends State<MyHomePage> {
final jwt = await _storageHelper.read(StorageKey.jwt); final jwt = await _storageHelper.read(StorageKey.jwt);
apiClient = ApiClient(baseUrl: url!, token: jwt); apiClient = ApiClient(baseUrl: url!, token: jwt);
// TODO: check if really logged in // TODO: check if really logged in
return await apiClient!.fetchSheets(); final sheets = await apiClient!.fetchSheets();
log("${sheets.length} sheets fetched");
return sheets;
// return api.main(); // return api.main();
// final directory = await getApplicationDocumentsDirectory(); // final directory = await getApplicationDocumentsDirectory();

View File

@@ -1,37 +1,16 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
class Sheet { class Sheet {
final String uuid; final String uuid;
final String name; final String name;
final String composerUuid; final String composerUuid;
final DateTime releaseDate; final String composerName;
final String file;
final String fileHash;
final bool wasUploaded;
final int uploaderId;
final DateTime createdAt;
final DateTime updatedAt;
final DateTime lastOpened;
final List<String> tags;
final String informationText;
Sheet({ Sheet({
required this.uuid, required this.uuid,
required this.name, required this.name,
required this.composerUuid, required this.composerUuid,
required this.releaseDate, required this.composerName,
required this.file,
required this.fileHash,
required this.wasUploaded,
required this.uploaderId,
required this.createdAt,
required this.updatedAt,
required this.lastOpened,
required this.tags,
required this.informationText,
}); });
// Factory constructor for creating a Sheet from JSON // Factory constructor for creating a Sheet from JSON
@@ -40,37 +19,95 @@ class Sheet {
uuid: json['uuid'], uuid: json['uuid'],
name: json['sheet_name'], name: json['sheet_name'],
composerUuid: json['composer_uuid'], composerUuid: json['composer_uuid'],
releaseDate: DateTime.parse(json['release_date']), composerName: json['composer_name'],
file: json['file'],
fileHash: json['file_hash'],
wasUploaded: json['was_uploaded'],
uploaderId: json['uploader_id'],
createdAt: DateTime.parse(json['created_at']),
updatedAt: DateTime.parse(json['updated_at']),
lastOpened: DateTime.parse(json['last_opened']),
tags: List<String>.from(json['tags']),
informationText: json['information_text'],
); );
} }
} }
class SheetsWidget extends StatelessWidget { class SheetsWidget extends StatefulWidget {
final List<Sheet> sheets; final List<Sheet> sheets;
final ValueSetter<Sheet> callback; final ValueSetter<Sheet> callback;
const SheetsWidget({super.key, required this.sheets, required this.callback}); const SheetsWidget({super.key, required this.sheets, required this.callback});
@override @override
Widget build(context) { _SheetsWidgetState createState() => _SheetsWidgetState();
return ListView.builder( }
itemCount: sheets.length,
itemBuilder: (context, index) { class _SheetsWidgetState extends State<SheetsWidget> {
var sheet = sheets[index]; late List<Sheet> filteredSheets;
return ListTile( final TextEditingController _searchController = TextEditingController();
title: Text(sheet.name),
subtitle: Text(sheet.uuid), @override
onTap: () => callback(sheet), void initState() {
); super.initState();
filteredSheets = widget.sheets;
_searchController.addListener(_filterSheets);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
void _filterSheets() {
setState(() {
String query = _searchController.text.toLowerCase().trim();
List<String> terms = query.split(RegExp(r'\s+')); // Split by whitespace
filteredSheets = widget.sheets.where((sheet) {
String name = sheet.name.toLowerCase();
String composer = sheet.composerName.toLowerCase();
// Each term must be found in either the name or composer
return terms
.every((term) => name.contains(term) || composer.contains(term));
}).toList();
}); });
} }
void _clearSearch() {
_searchController.clear();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: 'Search...',
prefixIcon: const Icon(Icons.search),
suffixIcon: _searchController.text.isNotEmpty
? IconButton(
icon: const Icon(Icons.clear),
onPressed: _clearSearch,
)
: null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
Expanded(
child: ListView.builder(
itemCount: filteredSheets.length,
itemBuilder: (context, index) {
var sheet = filteredSheets[index];
return ListTile(
title: Text(sheet.name),
subtitle: Text(sheet.composerName),
onTap: () => widget.callback(sheet),
);
},
),
),
],
);
}
} }