add batch game info request
This commit is contained in:
parent
f6d40b8f2e
commit
d916014872
@ -44,6 +44,19 @@ async fn get_game(
|
||||
games.iter().find(|g| g.title == title).cloned()
|
||||
}
|
||||
|
||||
#[post("/games/batch", data = "<req>")]
|
||||
async fn get_games_batch(
|
||||
_token: auth::Token,
|
||||
game_list: &rocket::State<Mutex<Vec<Game>>>,
|
||||
req: proto_utils::Proto<items::GetGameInfoRequest>,
|
||||
) -> items::GameList {
|
||||
let games = game_list.lock().await;
|
||||
let req = req.into_inner();
|
||||
let mut games = games.clone();
|
||||
games.retain(|g| req.games.contains(&g.title));
|
||||
items::GameList { games }
|
||||
}
|
||||
|
||||
#[get("/games")]
|
||||
async fn get_games(
|
||||
_token: auth::Token,
|
||||
@ -319,7 +332,8 @@ async fn main() -> Result<(), std::io::Error> {
|
||||
add_opinion,
|
||||
remove_opinion,
|
||||
add_game,
|
||||
get_game_thumbnail
|
||||
get_game_thumbnail,
|
||||
get_games_batch
|
||||
],
|
||||
)
|
||||
.mount(
|
||||
|
||||
@ -116,6 +116,14 @@ export interface RemoveOpinionRequest {
|
||||
gameTitle: string;
|
||||
}
|
||||
|
||||
export interface GetGameInfoRequest {
|
||||
games: string[];
|
||||
}
|
||||
|
||||
export interface GameInfoResponse {
|
||||
games: Game[];
|
||||
}
|
||||
|
||||
function createBasePerson(): Person {
|
||||
return { name: "", opinion: [] };
|
||||
}
|
||||
@ -1213,6 +1221,122 @@ export const RemoveOpinionRequest: MessageFns<RemoveOpinionRequest> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGetGameInfoRequest(): GetGameInfoRequest {
|
||||
return { games: [] };
|
||||
}
|
||||
|
||||
export const GetGameInfoRequest: MessageFns<GetGameInfoRequest> = {
|
||||
encode(message: GetGameInfoRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
for (const v of message.games) {
|
||||
writer.uint32(10).string(v!);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GetGameInfoRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGetGameInfoRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.games.push(reader.string());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): GetGameInfoRequest {
|
||||
return { games: globalThis.Array.isArray(object?.games) ? object.games.map((e: any) => globalThis.String(e)) : [] };
|
||||
},
|
||||
|
||||
toJSON(message: GetGameInfoRequest): unknown {
|
||||
const obj: any = {};
|
||||
if (message.games?.length) {
|
||||
obj.games = message.games;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<GetGameInfoRequest>, I>>(base?: I): GetGameInfoRequest {
|
||||
return GetGameInfoRequest.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<GetGameInfoRequest>, I>>(object: I): GetGameInfoRequest {
|
||||
const message = createBaseGetGameInfoRequest();
|
||||
message.games = object.games?.map((e) => e) || [];
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGameInfoResponse(): GameInfoResponse {
|
||||
return { games: [] };
|
||||
}
|
||||
|
||||
export const GameInfoResponse: MessageFns<GameInfoResponse> = {
|
||||
encode(message: GameInfoResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
for (const v of message.games) {
|
||||
Game.encode(v!, writer.uint32(10).fork()).join();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameInfoResponse {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameInfoResponse();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.games.push(Game.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): GameInfoResponse {
|
||||
return { games: globalThis.Array.isArray(object?.games) ? object.games.map((e: any) => Game.fromJSON(e)) : [] };
|
||||
},
|
||||
|
||||
toJSON(message: GameInfoResponse): unknown {
|
||||
const obj: any = {};
|
||||
if (message.games?.length) {
|
||||
obj.games = message.games.map((e) => Game.toJSON(e));
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<GameInfoResponse>, I>>(base?: I): GameInfoResponse {
|
||||
return GameInfoResponse.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<GameInfoResponse>, I>>(object: I): GameInfoResponse {
|
||||
const message = createBaseGameInfoResponse();
|
||||
message.games = object.games?.map((e) => Game.fromPartial(e)) || [];
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
/** Authentication service */
|
||||
export interface AuthService {
|
||||
Login(request: LoginRequest): Promise<LoginResponse>;
|
||||
@ -1255,6 +1379,7 @@ export interface MainService {
|
||||
GetGames(request: GetGamesRequest): Promise<GameList>;
|
||||
AddGame(request: Game): Promise<Game>;
|
||||
AddOpinion(request: AddOpinionRequest): Promise<Person>;
|
||||
GetGameInfo(request: GetGameInfoRequest): Promise<GameInfoResponse>;
|
||||
}
|
||||
|
||||
export const MainServiceServiceName = "items.MainService";
|
||||
@ -1268,6 +1393,7 @@ export class MainServiceClientImpl implements MainService {
|
||||
this.GetGames = this.GetGames.bind(this);
|
||||
this.AddGame = this.AddGame.bind(this);
|
||||
this.AddOpinion = this.AddOpinion.bind(this);
|
||||
this.GetGameInfo = this.GetGameInfo.bind(this);
|
||||
}
|
||||
GetGame(request: GameRequest): Promise<Game> {
|
||||
const data = GameRequest.encode(request).finish();
|
||||
@ -1292,6 +1418,12 @@ export class MainServiceClientImpl implements MainService {
|
||||
const promise = this.rpc.request(this.service, "AddOpinion", data);
|
||||
return promise.then((data) => Person.decode(new BinaryReader(data)));
|
||||
}
|
||||
|
||||
GetGameInfo(request: GetGameInfoRequest): Promise<GameInfoResponse> {
|
||||
const data = GetGameInfoRequest.encode(request).finish();
|
||||
const promise = this.rpc.request(this.service, "GetGameInfo", data);
|
||||
return promise.then((data) => GameInfoResponse.decode(new BinaryReader(data)));
|
||||
}
|
||||
}
|
||||
|
||||
interface Rpc {
|
||||
|
||||
@ -3,6 +3,8 @@ import {
|
||||
Person,
|
||||
PersonList as PersonListProto,
|
||||
Game as GameProto,
|
||||
GetGameInfoRequest,
|
||||
GameInfoResponse,
|
||||
} from "../items";
|
||||
import { apiFetch } from "./api";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -72,22 +74,29 @@ export function GameFilter() {
|
||||
.filter(([, players]) => players.size === 0)
|
||||
.map(([game]) => game);
|
||||
|
||||
const games = game_titles.map(async (title) => {
|
||||
if (metaData[title]) {
|
||||
console.log("returned cached metadata");
|
||||
return metaData[title];
|
||||
}
|
||||
return await apiFetch(`/api/game/${encodeURIComponent(title)}`)
|
||||
let games = game_titles.filter((title) => metaData[title]).map((title) => metaData[title]);
|
||||
const gamesToFetch = GetGameInfoRequest.encode(
|
||||
GetGameInfoRequest.create({
|
||||
games: game_titles.filter((title) => !metaData[title]),
|
||||
})
|
||||
).finish();
|
||||
|
||||
apiFetch("/api/games/batch", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
},
|
||||
body: gamesToFetch,
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buffer) => {
|
||||
const game = GameProto.decode(new Uint8Array(buffer)) as GameProto;
|
||||
metaData[title] = game;
|
||||
return game;
|
||||
})
|
||||
.catch((err) => console.error("Failed to fetch game:", err));
|
||||
const list = GameInfoResponse.decode(new Uint8Array(buffer));
|
||||
games = games.concat(list.games);
|
||||
|
||||
games.forEach((game) => {
|
||||
metaData[game.title] = game;
|
||||
});
|
||||
|
||||
Promise.all(games).then((games) => {
|
||||
const filteredGames = games.filter((g) => {
|
||||
const game = g as GameProto;
|
||||
return (
|
||||
|
||||
@ -459,7 +459,7 @@ export function GameList({ onShowToast }: Props) {
|
||||
"Content-Type": "application/octet-stream",
|
||||
},
|
||||
body: RemoveOpinionRequest.encode(
|
||||
AddOpinionRequest.create({
|
||||
RemoveOpinionRequest.create({
|
||||
gameTitle: title,
|
||||
})
|
||||
).finish(),
|
||||
|
||||
@ -28,6 +28,7 @@ enum Source {
|
||||
}
|
||||
|
||||
message PersonList { repeated Person person = 1; }
|
||||
|
||||
message GameList { repeated Game games = 1; }
|
||||
|
||||
// Authentication messages
|
||||
@ -65,6 +66,7 @@ service AuthService {
|
||||
}
|
||||
|
||||
message GameRequest { string title = 1; }
|
||||
|
||||
message GetGamesRequest {}
|
||||
|
||||
message AddOpinionRequest {
|
||||
@ -74,9 +76,18 @@ message AddOpinionRequest {
|
||||
|
||||
message RemoveOpinionRequest { string game_title = 1; }
|
||||
|
||||
message GetGameInfoRequest {
|
||||
repeated string games = 1;
|
||||
}
|
||||
|
||||
message GameInfoResponse {
|
||||
repeated Game games = 1;
|
||||
}
|
||||
|
||||
service MainService {
|
||||
rpc GetGame(GameRequest) returns (Game);
|
||||
rpc GetGames(GetGamesRequest) returns (GameList);
|
||||
rpc AddGame(Game) returns (Game);
|
||||
rpc AddOpinion(AddOpinionRequest) returns (Person);
|
||||
rpc GetGameInfo(GetGameInfoRequest) returns (GameInfoResponse);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user