feat: Add functionality to remove a user's game opinion via a new API endpoint and UI button.
This commit is contained in:
@@ -112,6 +112,10 @@ export interface AddOpinionRequest {
|
||||
wouldPlay: boolean;
|
||||
}
|
||||
|
||||
export interface RemoveOpinionRequest {
|
||||
gameTitle: string;
|
||||
}
|
||||
|
||||
function createBasePerson(): Person {
|
||||
return { name: "", opinion: [] };
|
||||
}
|
||||
@@ -1151,6 +1155,64 @@ export const AddOpinionRequest: MessageFns<AddOpinionRequest> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseRemoveOpinionRequest(): RemoveOpinionRequest {
|
||||
return { gameTitle: "" };
|
||||
}
|
||||
|
||||
export const RemoveOpinionRequest: MessageFns<RemoveOpinionRequest> = {
|
||||
encode(message: RemoveOpinionRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.gameTitle !== "") {
|
||||
writer.uint32(10).string(message.gameTitle);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RemoveOpinionRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRemoveOpinionRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.gameTitle = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): RemoveOpinionRequest {
|
||||
return { gameTitle: isSet(object.gameTitle) ? globalThis.String(object.gameTitle) : "" };
|
||||
},
|
||||
|
||||
toJSON(message: RemoveOpinionRequest): unknown {
|
||||
const obj: any = {};
|
||||
if (message.gameTitle !== "") {
|
||||
obj.gameTitle = message.gameTitle;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<RemoveOpinionRequest>, I>>(base?: I): RemoveOpinionRequest {
|
||||
return RemoveOpinionRequest.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<RemoveOpinionRequest>, I>>(object: I): RemoveOpinionRequest {
|
||||
const message = createBaseRemoveOpinionRequest();
|
||||
message.gameTitle = object.gameTitle ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
/** Authentication service */
|
||||
export interface AuthService {
|
||||
Login(request: LoginRequest): Promise<LoginResponse>;
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Person as PersonProto,
|
||||
Opinion,
|
||||
AddOpinionRequest,
|
||||
RemoveOpinionRequest,
|
||||
} from "../items";
|
||||
import { Link } from "react-router-dom";
|
||||
import { apiFetch, get_auth_status } from "./api";
|
||||
@@ -458,7 +459,33 @@ export function GameList() {
|
||||
<ul className="grid-container">
|
||||
{games.map((game) => {
|
||||
const opinion = opinions.find((op) => op.title === game.title);
|
||||
function handleOpinion(title: string, wouldPlay: boolean): void {
|
||||
function handleOpinion(title: string, number: number): void {
|
||||
if (number == 2) {
|
||||
apiFetch("/api/opinion", {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
},
|
||||
body: RemoveOpinionRequest.encode(
|
||||
AddOpinionRequest.create({
|
||||
gameTitle: title,
|
||||
})
|
||||
).finish(),
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((resBuffer) => {
|
||||
const response = PersonProto.decode(
|
||||
new Uint8Array(resBuffer)
|
||||
);
|
||||
|
||||
setOpinions(response.opinion);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const wouldPlay = number == 1;
|
||||
apiFetch(`/api/opinion`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -496,6 +523,7 @@ export function GameList() {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: "50%",
|
||||
borderColor: opinion
|
||||
? opinion.wouldPlay
|
||||
? "#4caf50" // would play (green)
|
||||
@@ -525,7 +553,7 @@ export function GameList() {
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => handleOpinion(game.title, true)}
|
||||
onClick={() => handleOpinion(game.title, 1)}
|
||||
style={{
|
||||
width: "50%",
|
||||
borderColor: "#4caf50",
|
||||
@@ -534,7 +562,16 @@ export function GameList() {
|
||||
Would Play
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleOpinion(game.title, false)}
|
||||
onClick={() => handleOpinion(game.title, 2)}
|
||||
style={{
|
||||
width: "50%",
|
||||
borderColor: "#ffff00",
|
||||
}}
|
||||
>
|
||||
Neutral
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleOpinion(game.title, 0)}
|
||||
style={{
|
||||
width: "50%",
|
||||
borderColor: "#f44336",
|
||||
|
||||
Reference in New Issue
Block a user