Skip to content

Commit

Permalink
[update] 記録の動的OGP,トップメニューの静的OGPを設定
Browse files Browse the repository at this point in the history
[fix] validatorのAjvへ渡すオブジェクトを適切なものへ置換し、警告メッセージを出さないように。
  • Loading branch information
Appbird committed Aug 12, 2021
1 parent d46b865 commit 41a7d87
Show file tree
Hide file tree
Showing 27 changed files with 133 additions and 68 deletions.
3 changes: 3 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
{
"source": "/api/**",
"function": "app"
},{
"source": "/ogpDetailView",
"function": "ogp"
}
]
}
Expand Down
19 changes: 18 additions & 1 deletion functions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { authentication } from "./server/function/foundation/auth";
import { IReceivedDataAtServerNeedAuthentication } from "../../src/ts/type/api/transmissionBase";
import { checkPrivilege } from "./checkPrivilege";
import { errorCatcher } from "./errorCatcher";
import { generateOGP } from "./ogp";

const app = express();
app.use(express.json())
Expand Down Expand Up @@ -46,4 +47,20 @@ apiList.forEach( (value,key) => {

exports.app = functions.https.onRequest(app);


exports.ogp = functions.https.onRequest(async (request,response) => {
response.set("Cache-Control", "public, max-age=600, s-maxage=600");
const url = new URL(request.url, `http://${request.headers.host}`);
const gs = url.searchParams.get("gs")
const gm = url.searchParams.get("gm")
const id = url.searchParams.get("id")
if (gs === null||gm=== null||id===null) {
response.status(404).send(`404 Not Found`)
return;
}
try {
const result = await generateOGP(recordDataBase,gs,gm,id)
response.status(200).send(result)
} catch(err){
response.status(500).send(`500 ${err.message}`)
}
})
48 changes: 48 additions & 0 deletions functions/src/ogp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { converseMiliSecondsIntoTime } from "../../src/ts/utility/timeUtility";
import { RecordDataBase } from "./server/firestore/RecordDataBase";
import { ControllerOfTableForResolvingID } from "./server/recordConverter/ControllerOfTableForResolvingID";
// 参考
// https://qiita.com/yuneco/items/5e526464939082862f5d
// https://qiita.com/stin_dev/items/41ac4acb6ee7e1bc2d50

//#CH 404や500の時のOGPも用意したい。

export async function generateOGP(recordDataBase:RecordDataBase,gs:string,gm:string,id:string){
const gameSystem =await recordDataBase.getGameSystemInfo(gs)
const gameMode =await recordDataBase.getGameModeInfo(gs,gm)
const record =await recordDataBase.getRecord(gs,gm,id)
const cotfr = new ControllerOfTableForResolvingID(recordDataBase)
const recordResolved = await cotfr.convertRecordIntoRecordResolved(record,"English")
const score = gameMode.scoreType === "time" ? converseMiliSecondsIntoTime(record.score) : record.score.toString()

const title = `Record by ${recordResolved.runnerName} in ${gameSystem.English} / ${gameMode.English}`
const site_title = "Kirby-Speed/Score-Recorders"
const imageURL = "https://firebasestorage.googleapis.com/v0/b/kss-recorders.appspot.com/o/icon.png?alt=media&token=bcb35206-fc4c-4d04-b6cd-45bbab213cc9"
const url = `https://kss-recorders.web.app`
const description = `${score} : [${recordResolved.regulation.abilityNames.join(", ")}] vs. [${recordResolved.regulation.targetName}]`
return `
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>${site_title}</title>
<meta property="og:title" content="${title}">
<meta property="og:image" content="${imageURL}">
<meta property="og:description" content="${description}">
<meta property="og:url" content="${url}">
<meta property="og:type" content="article">
<meta property="og:site_name" content="${url}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="${site_title}">
<meta name="twitter:title" content="${title}">
<meta name="twitter:image" content="${imageURL}">
<meta name="twitter:description" content="${description}">
<meta name="og:url" content="https://kss-recorders.web.app/?state=detailView&gs=${gs}&gm=${gm}&id=${id}&ogp=0">
</head>
<body>
<script> window.location = "https://kss-recorders.web.app/?state=detailView&gs=${gs}&gm=${gm}&id=${id}"</script>
</body>
</html>
`;

}
17 changes: 11 additions & 6 deletions functions/src/server/firestore/RecordDataBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,17 @@ export class RecordDataBase{
const runner = await this.getRunnerInfo(record.runnerID)
const gameSystem = await this.getGameSystemInfo(rrg.gameSystemID);
const gameMode = await this.getGameModeInfo(rrg.gameSystemID,rrg.gameModeID);
const userHaveRunThisGameSystem = runner.idOfGameSystemRunnerHavePlayed.find((info) => info.id === rrg.gameSystemID)
const userHaveRunThisGameMode = runner.idOfGameModeRunnerHavePlayed.find((info) => info.id === `${rrg.gameSystemID}/${rrg.gameModeID}`)
if (!userHaveRunThisGameSystem) runner.idOfGameSystemRunnerHavePlayed.push({id:rrg.gameSystemID,times:1})
else userHaveRunThisGameSystem.times += 1;
if (!userHaveRunThisGameMode) runner.idOfGameModeRunnerHavePlayed.push({id:`${rrg.gameSystemID}/${rrg.gameModeID}`,times:1})
else userHaveRunThisGameMode.times += 1;
let userHaveRunThisGameSystem = runner.idOfGameSystemRunnerHavePlayed.find((info) => info.id === rrg.gameSystemID)
let userHaveRunThisGameMode = runner.idOfGameModeRunnerHavePlayed.find((info) => info.id === `${rrg.gameSystemID}/${rrg.gameModeID}`)
if (!userHaveRunThisGameSystem){
userHaveRunThisGameSystem = {id:rrg.gameSystemID,times:1}
runner.idOfGameSystemRunnerHavePlayed.push({id:rrg.gameSystemID,times:1})
} else userHaveRunThisGameSystem.times += 1;

if (!userHaveRunThisGameMode){
userHaveRunThisGameMode = {id:rrg.gameModeID,times:1}
runner.idOfGameModeRunnerHavePlayed.push({id:`${rrg.gameSystemID}/${rrg.gameModeID}`,times:1})
} else userHaveRunThisGameMode.times += 1;
runner.theNumberOfPost++;

await this.modifyGameSystemInfo(gameSystem.id,{
Expand Down
45 changes: 10 additions & 35 deletions functions/src/server/function/webhooks/Notificator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ScoreType } from "../../../../../src/ts/type/list/IGameModeItem";
//#NOTE これの実行には{webhookURL:string}型のオブジェクトが記述されたjsonファイルを書き込んでおく必要がある。
//#CTODO こいつがちゃんと投稿されるか確認する。
export class Notifier{
private readonly host:string = "http://localhost:5000"
private readonly host:string = "https://kss-recorders.web.app"
private readonly recordDatabase:RecordDataBase
constructor(recordDatabase:RecordDataBase){
this.recordDatabase = recordDatabase;
Expand All @@ -20,42 +20,17 @@ export class Notifier{
}){
const rr = record.regulation
const rrg = rr.gameSystemEnvironment
await fetch(webhookURL[type],{
await fetch(webhookURL[type],
{
method:"POST",
headers:{
"Content-Type":"application/json"
},
body:JSON.stringify({
color: colorcode,
content: content,
embeds:{
title: `KSSRs/${rrg.gameSystemName}/${rrg.gameModeName}/${rr.targetName}`,
url: `${this.host}/record/${rrg.gameSystemID}/${rrg.gameModeID}/${record.id}`,
author:{
name:record.runnerName,
url:`${this.host}/user/${record.runnerID}`,
icon_url:userIconURL
},
footer:{
text:"Kirby-Speed/Score-Recorders",
url:this.host
},
field:[{
name:`:star: Ability`,
value:rr.abilityNames.join(`,`)
},
{
name:`:flag_white: Target`,
value: rr.targetName

},{
name:`:clock3: ${scoreType === "time" ? "Time" : "Score"}`,
value: scoreType === "time" ? converseMiliSecondsIntoTime(record.score) : record.score
}]
},

})
"content": `${content}\n\n> ${
(scoreType === "time") ? converseMiliSecondsIntoTime(record.score):record.score} : ${record.regulation.abilityNames.join(",")} vs. ${record.regulation.targetName}\n${this.host}/?state=detailView&gs=${rrg.gameSystemID}&gm=${rrg.gameModeID}&id=${record.id}`
})
})
}
async sendRecordRegisteredMessage(record:IRecordResolved){
const rr = record.regulation
Expand All @@ -64,7 +39,7 @@ export class Notifier{
const userIconURL = (await this.recordDatabase.getRunnerInfo(record.runnerID)).photoURL;
const gameMode = await this.recordDatabase.getGameModeInfo(rrg.gameSystemID,rrg.gameModeID)
this.sendMesssageToDiscord("submit",{
content: `:mailbox_with_mail: New Submission! @[${gameSystem.English}/${gameMode.English}]`,
content: `:mailbox_with_mail: **New Submission(${record.id}) by ${record.runnerName}!** \n@${gameSystem.English}/${gameMode.English}`,
colorcode: 5620992,
record: record,
userIconURL: userIconURL,
Expand Down Expand Up @@ -95,7 +70,7 @@ export class Notifier{
})
}
await this.sendMesssageToDiscord("delete",{
content: `:closed_book: ${(recordResolved.moderatorIDs.length === 0) ? "Offer" : "Record"} is Deleted By ${deletedBy} @[${gameSystem.English}/${gameMode.English}]\n\nThe following JSON string is the data of the deleted Record.\`\`\`${JSON.stringify(record)}\`\`\`` + ((reason.length !== 0) ? `\n\n**reason:**\n\n ${reason}\n\n` : ""),
content: `:closed_book: ${(recordResolved.moderatorIDs.length === 0) ? "Offer" : "Record"}(**${record.id}**) is **Deleted By ${deletedBy}** \n@${gameSystem.English}/${gameMode.English}\n\nThe following JSON string is the data of the deleted Record.\`\`\`${JSON.stringify(record)}\`\`\`` + ((reason.length !== 0) ? `\n**reason:**\n ${reason}` : ""),
colorcode: 5620992,
record: recordResolved,
scoreType: gameMode.scoreType,userIconURL:userIconURL
Expand Down Expand Up @@ -126,7 +101,7 @@ export class Notifier{
}

await this.sendMesssageToDiscord("submit",{
content: `:closed_book: Record is Modified By ${modifiedBy} @[${gameSystem.English}/${gameMode.English}]`+ (reason.length !== 0) ? `\n\n**Reason:**\n\n ${reason}\n\n` : "",
content: `:closed_book: Record(**${recordResolved.id}**) is **Modified By ${modifiedBy}** \n@${gameSystem.English}/${gameMode.English}`+ ((reason.length !== 0) ? `\n\n**Reason:**\n ${reason}` : ""),
colorcode: 5620992,
record: recordResolved,
scoreType: gameMode.scoreType,userIconURL:userIconURL
Expand Down Expand Up @@ -155,7 +130,7 @@ export class Notifier{
})
}
await this.sendMesssageToDiscord("verify",{
content: `:mailbox_with_mail: Record ${record.id} (from ${record.runnerName}) in @[${gameSystem.English}/${gameMode.English}] is verified by ${moderatorName}.`,
content: `:mailbox_with_mail: Record(**${record.id}**) (from **${record.runnerName}**) is **verified by ${moderatorName}**.\n@${gameSystem.English}/${gameMode.English}`,
colorcode: 5620992,
record: record,
scoreType: gameMode.scoreType,userIconURL:userIconURL
Expand Down
13 changes: 13 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta property="og:title" content="Kirby-Speed/Score-Recorders">
<meta property="og:image" content="https://firebasestorage.googleapis.com/v0/b/kss-recorders.appspot.com/o/icon.png?alt=media&token=bcb35206-fc4c-4d04-b6cd-45bbab213cc9">
<meta property="og:description" content="KSSRsは、カービィシリーズのゲームのタイム/スコアを集積するTA/RTAプラットフォームです。">
<meta property="og:url" content="https://kss-recorders.web.app/">
<meta property="og:type" content="article">
<meta property="og:site_name" content="Kirby-Speed/Score-Recorders">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="Kirby-Speed/Score-Recorders">
<meta name="twitter:title" content="Kirby-Speed/Score-Recorders">
<meta name="twitter:image" content="https://firebasestorage.googleapis.com/v0/b/kss-recorders.appspot.com/o/icon.png?alt=media&token=bcb35206-fc4c-4d04-b6cd-45bbab213cc9">
<meta name="twitter:description" content="KSSRsは、カービィシリーズのゲームのタイム/スコアを集積するTA/RTAプラットフォームです。">


<link rel="stylesheet" type="text/css" href="https://npmcdn.com/flatpickr/dist/themes/dark.css">
<link rel="stylesheet" type="text/css" href="https://unpkg.com/notie/dist/notie.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/Administrator/HistoryAdministrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class HistoryAdministrator{
switch(this.app.state.state){
case "detailView":{
const obj = this.app.state.requiredObj as APIFunctions["record_detail"]["atServer"]
history.pushState(null,`Kirby-Speed/ScoreRecorders:${this.app.state.state}`,`/?state=detailView&gs=${obj.gameSystemEnv.gameSystemID}&gm=${obj.gameSystemEnv.gameModeID}&id=${obj.id}`)
history.pushState(null,`Kirby-Speed/ScoreRecorders:${this.app.state.state}`,`/ogpDetailView/?state=detailView&gs=${obj.gameSystemEnv.gameSystemID}&gm=${obj.gameSystemEnv.gameModeID}&id=${obj.id}`)
break;
}
case "userPageInWhole":{
Expand Down
6 changes: 4 additions & 2 deletions src/ts/client/view/parts/OfferFormView/OfferFormView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,19 @@ export class OfferFormView implements IView {
this.container.appendChild(createElementWithIdAndClass({className:"u-space3em"}))

this.setTargetChoices().then( () => {
if (defaultRecord !== undefined) this.loadDefaultRecord(defaultRecord);
if (defaultRecord !== undefined) return this.loadDefaultRecord(defaultRecord);
})

}
private loadDefaultRecord(record:IRecord){
private async loadDefaultRecord(record:IRecord){
const rr = record.regulation;
const rrg = rr.gameSystemEnvironment;
this.URLInput.value = record.link[0];
this.scoreInput.value = (this.app.state.scoreType === "time") ? converseMiliSecondsIntoTime(record.score):record.score.toString();
this.difficultyChoices.setSelected(rrg.gameDifficultyID)
this.abilityChoices.setSelected(rr.abilityIDs)

await this.setTargetChoices()
this.targetChoices.setSelected(rr.targetID)
this.tagInput.valueAsArray = record.tagName,
this.simpleMDE.value(record.note)
Expand Down
9 changes: 3 additions & 6 deletions src/ts/client/view/state/DetailViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,14 @@ const context = {
}
}
export class S_DetailViewer
extends PageStateBaseClass<APIFunctions["record_detail"]["atServer"]|{recordResolved:IRecordResolved},IAppUsedToChangeState>{
extends PageStateBaseClass<APIFunctions["record_detail"]["atServer"],IAppUsedToChangeState>{
async init(){
this.generateLoadingSpinner()
const notice = new NoticeView(appendElement(this.articleDOM,"div"),"detailView","portableURL",context.notice,this.app.state.language)
const operationDiv = this.articleDOM.appendChild(createElementWithIdAndClass({ id: "operation" }));
const detailDiv = this.articleDOM.appendChild(createElementWithIdAndClass({ id: "detail" }));
const relatedRecordDiv = this.articleDOM.appendChild(createElementWithIdAndClass({ id: "related" }));
let record:IRecordResolved;
if (((value:unknown):value is {recordResolved:IRecordResolved} => this.requiredObj.hasOwnProperty("recordResolved"))(this.requiredObj))
record = this.requiredObj.recordResolved;
else record = (await this.app.accessToAPI("record_detail",this.requiredObj)).result;
const record:IRecordResolved = (await this.app.accessToAPI("record_detail",this.requiredObj)).result;

const rrg = record.regulation.gameSystemEnvironment;
const rr = record.regulation;
Expand Down Expand Up @@ -147,7 +144,7 @@ export class S_DetailViewer
}])
}
private moveToModifyRecord(record:IRecord,gameSystem:IGameSystemInfoWithoutCollections,gameMode:IGameModeItemWithoutCollections){
if(!StateAdministrator.checkGameSystemEnvIsSet({gameMode,gameSystem})) return;
this.app.changeTargetGameMode({gameMode,gameSystem})
this.app.transition("modifyRecordForm",{targetGameMode:{gameMode,gameSystem},id:record.id})

}
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/UserPageInWhole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class S_UserPageInWhole
</div>
</div>
${writeElement(selectAppropriateDescription(gameMode,this.app.state.language),"p")}
${writeElement(selectAppropriateDescription(gameMode,this.app.state.language),"p","u-marginLeftRight2em")}
<div class="c-stateInfo u-left-aligined-forFlex">
<div class = "c-stateInfo__unit">
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/gamemodeListOfPlayersPlayed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class S_GamemodeListOfPlayersPlayed extends PageStateBaseClass<{runnersIn
</div>
</div>
${writeElement(selectAppropriateDescription(gameMode,this.app.state.language),"p")}
${writeElement(selectAppropriateDescription(gameMode,this.app.state.language),"p","u-marginLeftRight2em")}
<div class="c-stateInfo u-left-aligined-forFlex">
<div class = "c-stateInfo__unit">
Expand Down
3 changes: 2 additions & 1 deletion src/ts/client/view/state/offerForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ export class S_OfferForm
this.deleteLoadingSpinner();

this.app.notie.successAlert({Japanese:"記録の登録に成功しました!",English:"Registering Record is Completed Successfully!"})
const rrg = detailRecord.regulation.gameSystemEnvironment

await this.app.transition("detailView",{recordResolved:detailRecord});
await this.app.transition("detailView",{gameSystemEnv:{gameSystemID:rrg.gameSystemID,gameModeID:rrg.gameModeID},id:detailRecord.id,lang:this.app.state.language});

} catch(error){
this.app.errorCatcher(error,"記録の登録に失敗しました。")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {inspect} from 'util';
import Ajv = require('ajv');
import {IReceivedDataAtServer_getlist_UseId} from './IReceivedDataAtServer_getlist_UseId';
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":false});
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"useDefaults":false});

ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {inspect} from 'util';
import Ajv = require('ajv');
import {IReceivedDataAtServer_getlist_UseSIdId} from './IReceivedDataAtServer_getlist_UseSIdId';
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":false});
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"useDefaults":false});

ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {inspect} from 'util';
import Ajv = require('ajv');
import {IReceivedDataAtServer_getlist_UseSIdMIdId} from './IReceivedDataAtServer_getlist_UseSIdMIdId';
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":false});
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"useDefaults":false});

ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));

Expand Down
Loading

0 comments on commit 41a7d87

Please sign in to comment.