Create rating interface on songs view
If no ratings are present, provide a textbox to make a rating. If a rating is present, show the rating. Eventually, there will be a button that allows an additional rating to be made, and the ability to delete ratings
This commit is contained in:
parent
996022fe5f
commit
6f6aaecb8f
6 changed files with 36 additions and 7 deletions
|
|
@ -3,9 +3,11 @@ const jetzig = @import("jetzig");
|
|||
pub fn post(request: *jetzig.Request) !jetzig.View {
|
||||
var root = try request.data(.object);
|
||||
const params = try request.params();
|
||||
const id = params.getT(.integer, "song_id");
|
||||
const id = params.getT(.integer, "song_id").?;
|
||||
const score = if (params.getT(.integer, "score")) |score| @as(i16, @truncate(score)) else null;
|
||||
const review = params.getT(.string, "review");
|
||||
try root.put("song_id", id);
|
||||
try jetzig.database.Query(.Songrating).insert(.{ .song = id, .rating = score, .rating_text = review, .date = @divFloor(request.start_time, 1_000) }).execute(request.repo);
|
||||
try root.put("score", score);
|
||||
try root.put("review", review);
|
||||
|
||||
return request.render(.created);
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
{{.song_id}}
|
||||
{{.review}}
|
||||
<b>{{.score}}</b>: {{.review}} (Today)
|
||||
|
|
@ -59,5 +59,9 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
|
|||
|
||||
const timescale = try queries.entityQueryResult(request, queries.loadQuery(.song, .timescale), .{id_int});
|
||||
try root.put("yearly", timescale);
|
||||
|
||||
const ratings = try queries.entityQueryResult(request, queries.loadQuery(.song, .get_ratings), .{id_int});
|
||||
try root.put("reviews", ratings);
|
||||
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
@zig {
|
||||
const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
|
||||
const columns: ColumnChoices = &.{.song, .artistlist, .album, .date};
|
||||
const reviews = try zmpl.coerceArray(".reviews");
|
||||
}
|
||||
|
||||
<html>
|
||||
|
|
@ -25,13 +26,21 @@
|
|||
</div>
|
||||
<div style="display:flex;flex-direction:column;align-self:right">
|
||||
<h2>Rating</h2>
|
||||
<div id="review-container">
|
||||
@zig {
|
||||
if (reviews.len == 0) {
|
||||
<form>
|
||||
<input type="number" name="score" id="score" style="width:50px;height:30px">
|
||||
<textarea name="review" id="review" style="width:350px;height:100px"></textarea>
|
||||
<button hx-post="/ratings/songs" hx-vals='{"song_id":"{{.song.song_id}}"}' hx-target="#review-container" style="width:50px;height:30px">Post</button>
|
||||
</form>
|
||||
} else {
|
||||
for (reviews) |review| {
|
||||
<b>{{review.score}}</b>: {{review.review}} ({{review.date}})
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div id="review-container">No reviews</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -42,6 +42,8 @@ pub fn entityQueryResult(request: *jetzig.Request, query: GeneratedQuery, args:
|
|||
.artistlist = if (artist_list.getLastOrNull()) |_| try artist_list.toOwnedSlice() else null,
|
||||
.scrobbles = if (entity.scrobbles) |scrobbles| scrobbles else null,
|
||||
.date = if (entity.date) |date| date else null,
|
||||
.score = if (entity.score) |score| score else null,
|
||||
.review = if (entity.review) |review| review else null,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +51,7 @@ pub fn entityQueryResult(request: *jetzig.Request, query: GeneratedQuery, args:
|
|||
}
|
||||
|
||||
const EntityType = enum { scrobble, song, album, artist };
|
||||
const QueryTypeEnum = enum { firstlast, timescale, entities, get_songs, get_albums, get_scrobbles, appears, entity_info, datestreak, entities_by_name };
|
||||
const QueryTypeEnum = enum { firstlast, timescale, entities, get_songs, get_albums, get_scrobbles, appears, entity_info, datestreak, entities_by_name, get_ratings };
|
||||
|
||||
const GeneratedQuery = struct {
|
||||
entity: EntityType,
|
||||
|
|
@ -66,6 +68,8 @@ const UnifiedResult = struct {
|
|||
artist_id: ?i64 = null,
|
||||
scrobbles: ?i64 = null,
|
||||
date: ?[]const u8 = null,
|
||||
score: ?i16 = null,
|
||||
review: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
const EntityInfoResult = struct {
|
||||
|
|
@ -435,6 +439,15 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery {
|
|||
,
|
||||
else => unreachable,
|
||||
},
|
||||
.get_ratings => switch (entity) {
|
||||
.song =>
|
||||
\\SELECT rating AS score, rating_text AS review, TO_CHAR(date, 'YYYY-MM-DD') AS date
|
||||
\\FROM songratings
|
||||
\\WHERE song = $1
|
||||
\\ORDER BY date DESC;
|
||||
,
|
||||
else => unreachable,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ pub const TableRow = struct {
|
|||
artistlist: ?[]HyperlinkData = null,
|
||||
scrobbles: ?i64 = null,
|
||||
date: ?[]const u8 = null,
|
||||
score: ?i16 = null,
|
||||
review: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
pub const HyperlinkData = struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue