From 11140a748a640231724395788dcae2b093760a5f Mon Sep 17 00:00:00 2001 From: Julian Mutter Date: Sat, 24 Jan 2026 19:22:03 +0100 Subject: [PATCH] Fix api --- lib/api.dart | 16 ++++++++++------ lib/home_page.dart | 35 +++++++++++++++++------------------ lib/login_page.dart | 23 ++++++++++++----------- lib/sheet.dart | 13 ++++++++----- 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/lib/api.dart b/lib/api.dart index 5ec1c46..ca18879 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -17,15 +17,16 @@ class ApiClient { Future login(String username, String password) async { log.info("Logging in..."); - final url = '$baseUrl/login'; + final url = '$baseUrl/auth/login'; final response = await http.post( Uri.parse(url), headers: {'Content-Type': 'application/json'}, - body: jsonEncode({'email': username, 'password': password}), + body: jsonEncode({'username': username, 'password': password}), ); if (response.statusCode == 200) { - token = jsonDecode(response.body); + final responseData = jsonDecode(response.body); + token = responseData['token']; log.info('Login successful'); } else { throw Exception( @@ -55,6 +56,9 @@ class ApiClient { if (!throwExceptionIfStatusCodeNot200 || response.statusCode == 200) { return response; } else { + log.warning( + "Failed get request to '$url'! StatusCode: ${response.statusCode}\nResponseBody: ${response.body}", + ); throw Exception( 'GET request failed: ${response.statusCode} ${response.body}', ); @@ -120,19 +124,19 @@ class ApiClient { Future> fetchSheets() async { final response = await get( - "/list/sheets", + "/api/sheets/list", throwExceptionIfStatusCodeNot200: true, ); final data = jsonDecode(response.body); - return (data as List) + return (data['sheets'] as List) .map((sheet) => Sheet.fromJson(sheet as Map)) .toList(); } Future fetchPdfFileData(String sheetUuid) async { final response = await get( - '/sheet/pdf/$sheetUuid', + '/api/sheets/get/$sheetUuid', isBinary: true, throwExceptionIfStatusCodeNot200: true, ); diff --git a/lib/home_page.dart b/lib/home_page.dart index 20d6375..438eff5 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -58,37 +58,36 @@ class _MyHomePageState extends State with FullScreenListener { Future> acquireSheets() async { final url = await _storageHelper.readSecure(SecureStorageKey.url); final jwt = await _storageHelper.readSecure(SecureStorageKey.jwt); - apiClient = ApiClient(baseUrl: "${url!}/api", token: jwt); + apiClient = ApiClient(baseUrl: url!, token: jwt); // TODO: check if really logged in final sheets = await apiClient!.fetchSheets(); log.info("${sheets.length} sheets fetched"); - final sheetsSorted = await sortSheetsByAccessTime(sheets); + final sheetsSorted = await sortSheetsByRecency(sheets); log.info("${sheetsSorted.length} sheets sorted"); - final changeQueue = await _storageHelper.readChangeQueue(); - changeQueue.applyToSheets(sheetsSorted); - log.info("${changeQueue.length()} changes applied"); + // TODO: make work + // final changeQueue = await _storageHelper.readChangeQueue(); + // changeQueue.applyToSheets(sheetsSorted); + // log.info("${changeQueue.length()} changes applied"); return sheetsSorted; } - Future> sortSheetsByAccessTime(List sheets) async { + Future> sortSheetsByRecency(List sheets) async { final accessTimes = await _storageHelper.readSheetAccessTimes(); sheets.sort((a, b) { - final dateA = accessTimes[a.uuid]; - final dateB = accessTimes[b.uuid]; + var dateA = accessTimes[a.uuid]; + var dateB = accessTimes[b.uuid]; - if (dateB == null) { - // b has no date, sort below a - return -1; - } else if (dateA == null) { - // a has no date, sort below b - return 1; - } else { - // compare both and sort by date - return dateB.compareTo(dateA); + if (dateA == null || a.updatedAt.isAfter(dateA)) { + dateA = a.updatedAt; } + if (dateB == null || b.updatedAt.isAfter(dateB)) { + dateB = b.updatedAt; + } + + return dateB.compareTo(dateA); }); return sheets; @@ -109,7 +108,7 @@ class _MyHomePageState extends State with FullScreenListener { if (newState) { (await sheets).shuffle(); } else { - sheets = sortSheetsByAccessTime(await sheets); + sheets = sortSheetsByRecency(await sheets); } setState(() { diff --git a/lib/login_page.dart b/lib/login_page.dart index c8754b0..c20c14e 100644 --- a/lib/login_page.dart +++ b/lib/login_page.dart @@ -18,7 +18,7 @@ class _LoginPageState extends State { final TextEditingController _urlController = TextEditingController( text: "https://sheetable.julian-mutter.de", ); - final TextEditingController _emailController = TextEditingController(); + final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); final _formKey = GlobalKey(); @@ -40,12 +40,12 @@ class _LoginPageState extends State { return; } final url = await _storageHelper.readSecure(SecureStorageKey.url); - final email = await _storageHelper.readSecure(SecureStorageKey.email); + final username = await _storageHelper.readSecure(SecureStorageKey.email); if (url != null) { _urlController.text = url; } - if (email != null) { - _emailController.text = email; + if (username != null) { + _usernameController.text = username; } } @@ -58,17 +58,18 @@ class _LoginPageState extends State { } } - Future _login(String serverUrl, String email, String password) async { + Future _login( + String serverUrl, String username, String password) async { setState(() { _error = null; }); - final apiClient = ApiClient(baseUrl: "$serverUrl/api"); + final apiClient = ApiClient(baseUrl: serverUrl); try { - await apiClient.login(email, password); + await apiClient.login(username, password); await _storageHelper.writeSecure(SecureStorageKey.url, serverUrl); await _storageHelper.writeSecure(SecureStorageKey.jwt, apiClient.token!); - await _storageHelper.writeSecure(SecureStorageKey.email, email); + await _storageHelper.writeSecure(SecureStorageKey.email, username); await _navigateToMainPage(); } catch (e) { setState(() { @@ -98,7 +99,7 @@ class _LoginPageState extends State { if (_formKey.currentState!.validate()) { await _login( _urlController.text, - _emailController.text, + _usernameController.text, _passwordController.text, ); } @@ -123,9 +124,9 @@ class _LoginPageState extends State { textInputAction: TextInputAction.next, ), TextFormField( - controller: _emailController, + controller: _usernameController, validator: validateNotEmpty, - decoration: InputDecoration(labelText: 'Email'), + decoration: InputDecoration(labelText: 'Username'), textInputAction: TextInputAction.next, ), TextFormField( diff --git a/lib/sheet.dart b/lib/sheet.dart index 16ac268..2b331dc 100644 --- a/lib/sheet.dart +++ b/lib/sheet.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:sheetless/edit_bottom_sheet.dart'; import 'package:sheetless/storage_helper.dart'; @@ -11,21 +10,25 @@ class Sheet { String name; String composerUuid; String composerName; + DateTime updatedAt; Sheet({ required this.uuid, required this.name, required this.composerUuid, required this.composerName, + required this.updatedAt, }); // Factory constructor for creating a Sheet from JSON factory Sheet.fromJson(Map json) { + final composer = json['composer'] as Map?; return Sheet( - uuid: json['uuid'], - name: json['sheet_name'], - composerUuid: json['composer_uuid'], - composerName: json['composer_name'], + uuid: json['uuid'].toString(), + name: json['title'], + composerUuid: json['composer_uuid']?.toString() ?? '', + composerName: composer?['name'] ?? 'Unknown', + updatedAt: DateTime.parse(json['updated_at']), ); } }