feat: add new UI tabs for movies and series, including mobile-specific versions with search and pagination.

This commit is contained in:
Michael committed 2025-12-08 20:43:41 +01:00
1 parent d48d25f65e
commit 6a71f58a36
29 files changed
+78 -78

No files matched your search

+9 -9
View File
@@ -29,7 +29,7 @@ class AuthHandler {
return Response(400, body: jsonEncode({
'success': false,
'error': 'Username and password are required',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
// Verify credentials
@@ -38,7 +38,7 @@ class AuthHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Invalid credentials',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
// Create session
@@ -48,7 +48,7 @@ class AuthHandler {
'success': true,
'user': user.toJson(),
'token': session.token,
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -65,14 +65,14 @@ class AuthHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
db.deleteSession(token);
return Response.ok(jsonEncode({
'success': true,
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -89,7 +89,7 @@ class AuthHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final session = db.findSessionByToken(token);
@@ -97,7 +97,7 @@ class AuthHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Invalid or expired session',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final user = db.findUserById(session.userId);
@@ -105,12 +105,12 @@ class AuthHandler {
return Response(404, body: jsonEncode({
'success': false,
'error': 'User not found',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
return Response.ok(jsonEncode({
'user': user.toJson(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
+13 -13
View File
@@ -27,14 +27,14 @@ class PlaylistsHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final playlists = db.getPlaylists(userId);
return Response.ok(jsonEncode({
'playlists': playlists.map((p) => p.toJson()).toList(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -51,7 +51,7 @@ class PlaylistsHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final payload = jsonDecode(await request.readAsString()) as Map<String, dynamic>;
@@ -65,7 +65,7 @@ class PlaylistsHandler {
return Response(400, body: jsonEncode({
'success': false,
'error': 'Missing required fields',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final playlist = db.createPlaylist(
@@ -80,7 +80,7 @@ class PlaylistsHandler {
return Response.ok(jsonEncode({
'success': true,
'playlist': playlist.toJson(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -97,7 +97,7 @@ class PlaylistsHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
// Verify playlist belongs to user
@@ -106,14 +106,14 @@ class PlaylistsHandler {
return Response(404, body: jsonEncode({
'success': false,
'error': 'Playlist not found',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
if (existing.userId != userId) {
return Response(403, body: jsonEncode({
'success': false,
'error': 'Forbidden',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final payload = jsonDecode(await request.readAsString()) as Map<String, dynamic>;
@@ -135,7 +135,7 @@ class PlaylistsHandler {
return Response.ok(jsonEncode({
'success': true,
'playlist': playlist.toJson(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -152,7 +152,7 @@ class PlaylistsHandler {
return Response(401, body: jsonEncode({
'success': false,
'error': 'Unauthorized',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
// Verify playlist belongs to user
@@ -161,21 +161,21 @@ class PlaylistsHandler {
return Response(404,body: jsonEncode({
'success': false,
'error': 'Playlist not found',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
if (existing.userId != userId) {
return Response(403, body: jsonEncode({
'success': false,
'error': 'Forbidden',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
db.deletePlaylist(id);
return Response.ok(jsonEncode({
'success': true,
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
+6 -6
View File
@@ -37,7 +37,7 @@ class UsersHandler {
return Response.ok(jsonEncode({
'success': true,
'users': users.map((u) => u.toJson()).toList(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
body: jsonEncode({'success': false, 'error': e.toString()}),
@@ -62,21 +62,21 @@ class UsersHandler {
return Response.badRequest(body: jsonEncode({
'success': false,
'error': 'Missing required fields',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
if (db.findUserByUsername(username) != null) {
return Response.badRequest(body: jsonEncode({
'success': false,
'error': 'Username already exists',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
final user = db.createUser(username, password, isAdmin: isAdmin);
return Response.ok(jsonEncode({
'success': true,
'user': user.toJson(),
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
} catch (e) {
return Response.internalServerError(
@@ -100,7 +100,7 @@ class UsersHandler {
return Response.badRequest(body: jsonEncode({
'success': false,
'error': 'Missing password',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
db.updateUserPassword(id, password);
@@ -151,7 +151,7 @@ class UsersHandler {
return Response.badRequest(body: jsonEncode({
'success': false,
'error': 'Cannot delete yourself',
}), headers: {'Content-Type': 'application/json'});
}), headers: {'Content-Type': 'application/json'},);
}
db.deleteUser(id);